Conversation
Branch 최신화
THIP-TextHip#27 TopAppBar Pull, Merge
|
""" Walkthrough이 변경사항은 "모임" 페이지 및 관련 그룹/모임방 UI의 대규모 구현을 포함합니다. 여러 새로운 컴포저블 UI 컴포넌트, 데이터 모델, 뷰모델, 화면 및 프리뷰가 추가되었으며, 기존 컴포저블과 리소스의 네이밍 및 파라미터가 개선되었습니다. 빌드 설정과 테마, 문자열 리소스도 확장되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant GroupScreen
participant GroupViewModel
participant UIComponents
User->>GroupScreen: 화면 진입
GroupScreen->>GroupViewModel: myGroups, roomSections StateFlow 수집
GroupScreen->>UIComponents: MyGroupSectionHeader, GroupPager, GroupRoomDeadlineSection 등 렌더링
User->>GroupScreen: FAB 클릭/카드 클릭/필터 선택
GroupScreen->>GroupViewModel: onFabClick/onMyGroupCardClick/onRoomCardClick 호출
GroupViewModel-->>GroupScreen: 상태 업데이트 (필요 시)
Assessment against linked issues
Assessment against linked issues: Out-of-scope changes(해당 변경사항에서 범위를 벗어난 기능적 코드 변경은 발견되지 않았습니다.) Possibly related PRs
Suggested labels
Suggested reviewers
Poem
""" 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
✨ Finishing Touches
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. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 14
🧹 Nitpick comments (21)
app/src/main/java/com/texthip/thip/ui/theme/Color.kt (1)
20-20: 네이밍 컨벤션 불일치를 수정해주세요.다른 색상 상수들은 대문자로 시작하는데(
Purple,NeonGreen,Red등)genreColor만 소문자로 시작하여 일관성이 부족합니다.-val genreColor = Color(0xFFB5B35D) +val GenreColor = Color(0xFFB5B35D)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/SimplePagerIndicator.kt (1)
16-39: 기본 구현은 올바르지만 개선 사항을 고려해보세요.페이지 인디케이터의 기본 기능은 잘 구현되었습니다. 하지만 다음 개선사항을 고려해보세요:
@Composable fun SimplePagerIndicator( pageCount: Int, currentPage: Int, modifier: Modifier = Modifier ) { + if (pageCount <= 0) return + Row( modifier = modifier, horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { repeat(pageCount) { index -> Box( modifier = Modifier .padding(horizontal = 6.dp) .size(4.dp) .background( - color = if (currentPage == index) colors.White else colors.Grey02, + color = if (currentPage.coerceIn(0, pageCount - 1) == index) colors.White else colors.Grey02, shape = RoundedCornerShape(50) ) ) } } }선택적으로 페이지 전환 시 부드러운 애니메이션을 추가하는 것도 고려해보세요.
app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/BookData.kt (1)
5-11: 책 정보 모델링이 적절히 이루어졌습니다.
BookData클래스가 책의 기본 정보를 잘 모델링하고 있습니다. 현재 요구사항에 적합한 간단하고 명확한 구조입니다.향후 확장성을 고려한다면 다음 개선사항을 고려해보세요:
imageRes를@DrawableRes어노테이션으로 타입 안전성 강화description에 대한 길이 제한 고려- ISBN이나 출간일 등 추가 메타데이터 필드
+import androidx.annotation.DrawableRes + data class BookData( val title: String, val author: String, val publisher: String, val description: String, - val imageRes: Int = R.drawable.bookcover_sample + @DrawableRes val imageRes: Int = R.drawable.bookcover_sample )app/src/main/res/values/strings.xml (1)
56-56: 오타:groupPeroid→groupPeriod
Period의 철자가 잘못되었습니다. XML 키와 code-reference 모두 수정해야 합니다.- <string name="groupPeroid">모임 활동 기간</string> + <string name="group_period">모임 활동 기간</string>.idea/deploymentTargetSelector.xml (1)
5-5: IDE 설정 파일 커밋 여부 재검토 필요
.idea/*파일은 개발자별 설정이 달라 충돌을 유발할 수 있습니다. 팀에서 명시적으로 버전 관리하기로 합의된 파일인지 확인해주세요.app/src/main/java/com/texthip/thip/ui/myPage/myGroup/FilterRow.kt (1)
12-32: 잘 구현된 필터 컴포넌트입니다.상태 관리 패턴과 문자열 리소스 사용이 적절합니다. 유지보수성을 위해 하드코딩된 인덱스를 상수나 enum으로 교체하는 것을 고려해보세요.
+private const val ONGOING_INDEX = 0 +private const val RECRUITING_INDEX = 1 @Composable fun FilterRow( selectedIndex: Int, onSelect: (Int) -> Unit ) { Row( horizontalArrangement = Arrangement.spacedBy(12.dp) ) { OptionChipButton( text = stringResource(R.string.onGoing), isFilled = true, - isSelected = selectedIndex == 0, - onClick = { onSelect(0) } + isSelected = selectedIndex == ONGOING_INDEX, + onClick = { onSelect(ONGOING_INDEX) } ) OptionChipButton( text = stringResource(R.string.recruiting), isFilled = true, - isSelected = selectedIndex == 1, - onClick = { onSelect(1) } + isSelected = selectedIndex == RECRUITING_INDEX, + onClick = { onSelect(RECRUITING_INDEX) } ) } }app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomData.kt (1)
5-16: 포괄적인 데이터 클래스 설계가 우수합니다!그룹 룸의 모든 필요한 정보를 잘 포함하고 있고, 타입 안전성도 확보되어 있습니다. 다만 몇 가지 개선 사항을 고려해보세요:
daysLeft가 음수가 될 수 있는지 검증 로직 추가 고려members와maxMembers의 관계 검증 (members > maxMembers인 경우)data class GroupRoomData( val title: String, val isSecret: Boolean, val description: String, val period: String, - val members: Int, - val maxMembers: Int, - val daysLeft: Int, + val members: Int, + val maxMembers: Int, + val daysLeft: Int, // Consider validation: daysLeft >= 0 val genre: String, val bookData: BookData, val recommendations: List<CardItemRoomData> -) +) { + init { + require(members >= 0) { "Members count cannot be negative" } + require(maxMembers > 0) { "Max members must be positive" } + require(members <= maxMembers) { "Members cannot exceed max members" } + require(daysLeft >= 0) { "Days left cannot be negative" } + } +}app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupPager.kt (1)
42-48: 하드코딩된 값들을 상수로 분리하는 것을 고려해보세요스케일링 값들과 색상 로직을 더 관리하기 쉽게 만들 수 있습니다.
+private const val PEEK_SCALE = 0.86f +private const val CENTER_SCALE = 1f +private const val PEEK_ALPHA = 0.7f +private const val CENTER_ALPHA = 1f // 페이지와 현재페이지의 거리(0이면 중앙, 1/-1이면 peek) val distanceFromCenter = (pagerState.currentPage - page).toFloat() // scale 계산 (중앙은 1f, peek은 0.93~0.97f) -val scale = if (pagerState.currentPage == page) 1f else 0.86f +val scale = if (pagerState.currentPage == page) CENTER_SCALE else PEEK_SCALE // 색상 변경 (peek이면 밝은 회색, 중앙이면 흰색) val bgColor = if (pagerState.currentPage == page) colors.White else colors.DarkGrey -// alpha(살짝 흐리게)도 가능app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupMainCard.kt (2)
46-53: 그라데이션 좌표 하드코딩 개선그라데이션의
end좌표가Offset(1000f, 1000f)로 하드코딩되어 있어 다양한 화면 크기에서 일관되지 않을 수 있습니다.다음과 같이 상대적 좌표를 사용하는 것을 고려해보세요:
- val gradient = Brush.linearGradient( - colors = listOf( - colors.White, - colors.Grey01 - ), - start = Offset(0f, 0f), - end = Offset(1000f, 1000f) - ) + val gradient = Brush.linearGradient( + colors = listOf( + colors.White, + colors.Grey01 + ), + start = Offset.Zero, + end = Offset.Infinite + )
60-63: 카드 크기 하드코딩 개선 고려카드 크기가 320x176 dp로 하드코딩되어 있어 다양한 화면 크기에서 유연성이 부족할 수 있습니다.
반응형 디자인을 위해 비율 기반 크기 조정을 고려해보세요:
- modifier = Modifier - .width(320.dp) - .height(176.dp) - .clickable { onClick() }, + modifier = Modifier + .fillMaxWidth() + .aspectRatio(320f / 176f) + .clickable { onClick() },app/src/main/java/com/texthip/thip/ui/myPage/groupPage/DeadlineRoomSection.kt (1)
96-96: 룸 필터링 성능 최적화매 페이지 렌더링마다
rooms.filter { it.genreIndex == page }.take(3)를 실행하는 것은 룸 리스트가 클 때 성능 문제를 일으킬 수 있습니다.ViewModel에서 미리 필터링된 데이터를 제공하거나 remember를 사용하여 캐시하는 것을 고려해보세요:
+ val filteredCards = remember(rooms, page) { + rooms.filter { it.genreIndex == page }.take(3) + } - val cards = rooms.filter { it.genreIndex == page }.take(3) + val cards = filteredCardsapp/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoom.kt (1)
47-60: 테두리 조건부 적용 로직 개선테두리 적용을 위한 조건부 modifier 체이닝이 복잡합니다. 더 읽기 쉽게 개선할 수 있습니다.
다음과 같이 단순화할 수 있습니다:
- modifier = modifier - .fillMaxWidth() - .then( - if (hasBorder) - Modifier - .border( - width = 1.dp, - color = colors.Grey02, - shape = RoundedCornerShape(12.dp) - ) - else Modifier - ) - .clickable { onClick() }, + modifier = modifier + .fillMaxWidth() + .let { if (hasBorder) it.border(1.dp, colors.Grey02, RoundedCornerShape(12.dp)) else it } + .clickable { onClick() },app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt (1)
45-46: 고정 크기 카드의 반응형 디자인 고려카드 크기가 232x104 dp로 고정되어 있어 다양한 화면 크기에서 유연성이 부족할 수 있습니다.
반응형 디자인을 위해 비율 기반 크기 조정을 고려해보세요:
- modifier = modifier - .size(width = 232.dp, height = 104.dp) - .clickable { onClick() }, + modifier = modifier + .width(232.dp) + .height(104.dp) + .clickable { onClick() },또는 더 유연한 접근법:
+ modifier = modifier + .defaultMinSize(minWidth = 200.dp, minHeight = 90.dp) + .clickable { onClick() },app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomScreen.kt (3)
58-58: TODO 주석을 처리하세요.배경 이미지 추가에 대한 TODO가 있습니다. 이것이 완료되지 않으면 UI가 불완전할 수 있습니다.
배경 이미지 구현을 위한 코드를 생성하거나 이슈를 생성하시겠습니까?
70-84: 중복된 Spacer 코드를 리팩토링하세요.비밀방과 오픈방 분기에서 동일한
Spacer(Modifier.width(2.dp))가 중복됩니다.) { Text( text = detail.title, style = typography.bigtitle_b700_s22_h24, color = colors.White ) + Spacer(Modifier.width(2.dp)) - if (detail.isSecret) { - Spacer(Modifier.width(2.dp)) + if (detail.isSecret) { Icon( painter = painterResource(id = R.drawable.ic_lock), contentDescription = "비밀방", tint = colors.White ) } else { - Spacer(Modifier.width(2.dp)) Icon( painter = painterResource(id = R.drawable.ic_unlock), contentDescription = "오픈방", tint = colors.White ) }
275-373: 프리뷰 데이터가 너무 방대합니다.프리뷰 함수의 샘플 데이터가 매우 길어서 가독성을 해칩니다. 별도의 테스트 데이터 팩토리나 상수로 분리하는 것을 고려하세요.
예시:
object GroupRoomTestData { val sampleRecommendations = listOf(...) val sampleBookData = BookData(...) // ... }app/src/main/java/com/texthip/thip/ui/myPage/myGroup/MyGroupScreen.kt (1)
95-192: 프리뷰 데이터의 중복을 줄이세요.프리뷰에서 거의 동일한
CardItemRoomData객체가 반복적으로 생성되고 있습니다. 데이터 생성 함수를 만들어 중복을 줄이세요.private fun createSampleRoomData( isRecruiting: Boolean = true, endDate: Int = 3, participants: Int = 22, maxParticipants: Int = 30 ) = CardItemRoomData( title = "모임방 이름입니다. 모임방...", participants = participants, maxParticipants = maxParticipants, isRecruiting = isRecruiting, endDate = endDate, genreIndex = 0 )app/src/main/java/com/texthip/thip/ui/myPage/viewModel/MyPageViewModel.kt (2)
18-19: genres를 StateFlow로 만드는 것을 고려하세요.현재
_genres는 private val로 되어 있지만, 서버에서 동적으로 장르 목록을 받아올 가능성을 고려하면 StateFlow로 만드는 것이 확장성에 좋습니다.- private val _genres = listOf("문학", "과학·IT", "사회과학", "인문학", "예술") - val genres: List<String> get() = _genres + private val _genres = MutableStateFlow(listOf("문학", "과학·IT", "사회과학", "인문학", "예술")) + val genres: StateFlow<List<String>> = _genres
50-64: 이벤트 핸들러에 Navigation 처리를 추가하세요.현재 모든 이벤트 핸들러가 빈 구현입니다. Navigation 이벤트나 사이드 이펙트 처리를 위한 구조를 추가하는 것을 고려하세요.
예시:
fun onMyGroupHeaderClick() { // SharedFlow나 Channel을 사용한 Navigation 이벤트 발송 viewModelScope.launch { _navigationEvents.emit(NavigationEvent.ToMyGroupList) } }Navigation 이벤트 처리 구조를 생성하시겠습니까?
app/src/main/java/com/texthip/thip/ui/common/forms/FormTextFieldDefault.kt (2)
42-49: 문자 제한 로직이 중복됩니다.
displayText계산과onValueChange에서 동일한 문자 제한 로직이 중복됩니다. 별도 함수로 추출하여 DRY 원칙을 적용하세요.private fun String.limitLength(limit: Int, shouldLimit: Boolean): String { return if (shouldLimit && length > limit) substring(0, limit) else this } // 사용: val displayText = text.limitLength(limit, showLimit) onValueChange = { text = it.limitLength(limit, showLimit) }
71-86: 아이콘 상태 로직이 복잡합니다.
showIcon과text.isNotEmpty()조건이 중첩되어 있어 복잡합니다. 더 명확한 구조로 리팩토링하는 것을 고려하세요.trailingIcon = { if (showIcon) { val iconRes = if (text.isNotEmpty()) R.drawable.ic_x_circle_white else R.drawable.ic_x_circle val isClickable = text.isNotEmpty() Icon( painter = painterResource(id = iconRes), contentDescription = "Clear text", modifier = if (isClickable) Modifier.clickable { text = "" } else Modifier, tint = if (isClickable) Color.Unspecified else Color.Unspecified ) } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
app/src/main/res/drawable/bookcover_sample_small.pngis excluded by!**/*.png
📒 Files selected for processing (30)
.idea/deploymentTargetSelector.xml(1 hunks)app/build.gradle.kts(2 hunks)app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt(2 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardAlarm.kt(4 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoom.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardRoomBook.kt(2 hunks)app/src/main/java/com/texthip/thip/ui/common/forms/FormTextFieldDefault.kt(2 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/DeadlineRoomData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/DeadlineRoomSection.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GenreChipRow.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MainSectionHeader.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupCardData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupMainCard.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupPager.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/SearchTextField.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/SimplePagerIndicator.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/BookData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomScreen.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/myGroup/CardItemRoomData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/myGroup/FilterRow.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/myGroup/MyGroupScreen.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/screen/MyPageScreen.kt(0 hunks)app/src/main/java/com/texthip/thip/ui/myPage/viewModel/MyPageViewModel.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/theme/Color.kt(3 hunks)app/src/main/res/values/strings.xml(1 hunks)gradle/libs.versions.toml(2 hunks)
💤 Files with no reviewable changes (1)
- app/src/main/java/com/texthip/thip/ui/myPage/screen/MyPageScreen.kt
🧰 Additional context used
🧬 Code Graph Analysis (3)
app/src/main/java/com/texthip/thip/ui/myPage/myGroup/FilterRow.kt (1)
app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt (1)
OptionChipButton(28-74)
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GenreChipRow.kt (1)
app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt (1)
OptionChipButton(28-74)
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupPager.kt (2)
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupMainCard.kt (1)
MyGroupMainCard(39-144)app/src/main/java/com/texthip/thip/ui/myPage/groupPage/SimplePagerIndicator.kt (1)
SimplePagerIndicator(16-39)
🔇 Additional comments (23)
app/src/main/java/com/texthip/thip/ui/theme/Color.kt (1)
56-56: 색상 정의 구조는 올바르게 구현되었습니다.새로운
genreColor가 데이터 클래스와 기본 인스턴스에 일관되게 추가되었습니다. 하지만 앞서 언급한 네이밍 컨벤션 수정 시 이 부분들도 함께 업데이트가 필요합니다.Also applies to: 89-89
gradle/libs.versions.toml (1)
12-12: Navigation 의존성 버전 확인 완료
navigation-runtime-android2.9.0은 Google Maven(https://dl.google.com/dl/android/maven2/)에 등록된 가장 최신 안정(Stable) 버전이며, OSV 조회 결과 별도 보안 취약점이 보고되지 않았습니다.
의존성 추가를 승인합니다.app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt (1)
33-63: 상태 호이스팅 패턴으로 잘 리팩토링되었습니다.
isSelected매개변수를 추가하여 외부에서 선택 상태를 제어하도록 변경한 것은 Compose의 모범 사례를 잘 따르고 있습니다. 이로 인해:
- 컴포넌트의 재사용성이 향상됩니다
- 단방향 데이터 플로우 패턴을 준수합니다
- 상위 컴포넌트에서 선택 상태를 더 잘 관리할 수 있습니다
app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt (1)
10-18: Route 명칭과 화면 이름이 불일치합니다
Routes.MyPage.route에서GroupPageScreen을 호출하고 있습니다. 네이밍 불일치는 추후 라우팅 수정 시 혼동을 줄 수 있으니
Routes객체의 enum(또는 sealed class) 이름을GroupPage로 변경- 혹은 기존
MyPageScreen개념을 유지하고 파일/클래스 명을MyPageScreen으로 맞추기중 하나로 통일하는 것이 좋습니다.
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/DeadlineRoomData.kt (1)
5-8: 단순 데이터 구조 추가 확인 완료
불필요한 로직 없이 깔끔하게 정의되었습니다. 추후 Parcelable 등이 필요하면@Parcelize추가를 고려해주세요.app/build.gradle.kts (1)
55-65: 알파 버전 라이브러리 도입 전에 호환성 확인 필요
accompanist-pager0.35.0-alpha 는 Compose 1.6 미리보기 버전과 매칭됩니다. 현재 BOM이 안정화 버전이면 런타임 크래시가 발생할 수 있습니다. 또한 hard-coding 대신 version catalog(libs.versions.toml)로 관리하면 업그레이드가 수월합니다.app/src/main/java/com/texthip/thip/ui/common/cards/CardRoomBook.kt (1)
37-37: 함수명 변경 검증: 레거시 참조 확인 요청
DetailedDarkCard및PreviewDetailedDarkCard레거시 참조가 완전히 제거되었는지 수동으로 확인해주세요:rg -n "DetailedDarkCard" --type kotlin rg -n "PreviewDetailedDarkCard" --type kotlinapp/src/main/java/com/texthip/thip/ui/myPage/myGroup/CardItemRoomData.kt (1)
5-13: 잘 설계된 데이터 클래스입니다.모든 속성이 적절하게 명명되고 타입이 지정되었습니다.
endDate속성의 주석이 명확하게 의미를 전달합니다.app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupCardData.kt (1)
5-11: 명확하고 잘 구조화된 데이터 클래스입니다.
progress속성의 범위 문서화(0~100)가 명확하며, 모든 속성이 그룹 카드 표시에 필요한 정보를 적절히 담고 있습니다.app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GenreChipRow.kt (2)
12-30: 잘 구현된 장르 선택 컴포넌트입니다.
forEachIndexed사용과 외부 상태 관리 패턴이 적절하며,SpaceEvenly배치로 균등한 간격이 보장됩니다.
32-40: 실제적인 데이터를 활용한 우수한 프리뷰 구현입니다.한국어 장르명을 사용한 프리뷰가 실제 사용 환경을 잘 반영하고 있으며, 적절한 배경색과 크기 설정으로 시각적 검증이 용이합니다.
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MainSectionHeader.kt (1)
21-44: 깔끔한 헤더 컴포넌트 구현이 좋습니다!조건부 클릭 이벤트와 아이콘 표시 로직이 잘 구현되어 있습니다. 테마 색상과 타이포그래피를 일관성 있게 사용한 점도 훌륭합니다.
app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomData.kt (1)
18-18: 버튼 타입 enum 설계가 명확합니다!JOIN, CANCEL, CLOSE 타입들이 UI 액션을 명확하게 표현하고 있어 좋습니다.
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupPager.kt (1)
35-64: 페이저 구현이 훌륭합니다!스케일링과 투명도 효과를 통한 peek 기능이 잘 구현되어 있습니다. 특히 중앙 카드와 주변 카드의 시각적 차별화가 좋습니다.
app/src/main/java/com/texthip/thip/ui/myPage/groupPage/SearchTextField.kt (1)
55-62: 텍스트 필드 스타일링이 일관성 있게 잘 적용되었습니다!다크 테마에 맞는 색상 조합과 투명한 인디케이터 사용이 적절합니다.
app/src/main/java/com/texthip/thip/ui/common/cards/CardAlarm.kt (3)
37-39: 컴포넌트 리팩토링이 잘 수행되었습니다!
NotificationCard에서CardAlarm으로의 이름 변경과badgeText파라미터 추가가 적절합니다. 더 명확하고 유연한 API가 되었습니다.
78-80: 배지 패딩 개선이 좋습니다!고정된 크기 제약을 제거하고 패딩을 추가한 것이 더 유연한 디자인을 만들어냅니다.
152-194: 포괄적인 프리뷰 예제가 훌륭합니다!다양한 배지 텍스트("모임", "피드", "좋아요", "댓글")와 읽음 상태를 보여주는 예제들이 컴포넌트 테스트에 매우 유용합니다.
app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoom.kt (1)
112-116: 참가자 수 표시 로직 개선참가자 수 표시 로직이 명확하고 잘 구현되어 있습니다. 모집 중과 모집 완료 상태를 구분하여 적절한 정보를 보여줍니다.
app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomScreen.kt (1)
46-50: 네비게이션 콜백이 비어있습니다.
DefaultTopAppBar의onLeftClick콜백이 빈 구현으로 되어 있어 뒤로가기 기능이 작동하지 않을 것입니다.- onLeftClick = {}, + onLeftClick = { /* TODO: 네비게이션 뒤로가기 구현 */ },app/src/main/java/com/texthip/thip/ui/myPage/myGroup/MyGroupScreen.kt (2)
42-48: 필터링 로직이 효율적입니다.
remember를 사용해selectedIndex와allDataList가 변경될 때만 재계산하도록 최적화되어 있어 성능이 좋습니다.
54-57: 네비게이션 콜백이 비어있습니다.
DefaultTopAppBar의onLeftClick이 빈 구현으로 되어 있어 뒤로가기 기능이 작동하지 않을 것입니다.- onLeftClick = {}, + onLeftClick = { /* TODO: 네비게이션 뒤로가기 구현 */ },app/src/main/java/com/texthip/thip/ui/common/forms/FormTextFieldDefault.kt (1)
115-131: 프리뷰가 잘 구성되어 있습니다.두 가지 다른 설정의 컴포넌트를 보여주는 프리뷰가 잘 구성되어 있어 다양한 사용 사례를 확인할 수 있습니다.
app/src/main/res/values/strings.xml
Outdated
| <string name="groupRecruiting">"모집 "</string> | ||
| <string name="groupGenre">"장르 "</string> | ||
| <string name="deadlineString">마감 임박한 독서 모임방</string> | ||
| <string name="myGroup">내 모임방</string> | ||
| <string name="groupParticipant">%1$s명 참여</string> | ||
| <string name="groupProgress">"%1$s의 진행도 "</string> |
There was a problem hiding this comment.
🛠️ Refactor suggestion
값에 불필요한 큰따옴표와 공백이 포함되어 있습니다
groupRecruiting, groupGenre, groupProgress 값 앞뒤의 " 문자와 공백은 실제 UI에 그대로 노출됩니다. 의도된 스타일링이 아니라면 제거해야 합니다.
- <string name="groupRecruiting">"모집 "</string>
- <string name="groupGenre">"장르 "</string>
- <string name="groupProgress">"%1$s의 진행도 "</string>
+ <string name="group_recruiting">모집</string>
+ <string name="group_genre">장르</string>
+ <string name="group_progress">%1$s의 진행도</string>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In app/src/main/res/values/strings.xml lines 59 to 64, remove the unnecessary
double quotes and trailing spaces from the values of groupRecruiting,
groupGenre, and groupProgress strings to prevent them from appearing literally
in the UI. Ensure the string values contain only the intended text without extra
characters or spaces.
| @Preview(showBackground = true, backgroundColor = 0xFF000000, widthDp = 360) | ||
| @Composable | ||
| fun PreviewMainSectionHeader() { | ||
| MainSectionHeader(){} |
There was a problem hiding this comment.
Preview 함수 구문 오류 수정 필요
람다 표현식에 중괄호가 잘못 배치되어 있습니다.
다음과 같이 수정하세요:
- MainSectionHeader(){}
+ MainSectionHeader(onClick = {})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| MainSectionHeader(){} | |
| MainSectionHeader(onClick = {}) |
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MainSectionHeader.kt
at line 49, the lambda expression syntax is incorrect due to misplaced braces.
Fix the syntax by properly placing the curly braces around the lambda body to
conform to Kotlin's lambda expression rules.
| val pagerState = rememberPagerState( | ||
| initialPage = 0, | ||
| pageCount = { groupCards.size } | ||
| ) |
There was a problem hiding this comment.
빈 리스트 처리 로직 추가 필요
groupCards.size가 0일 때 페이저가 크래시할 수 있습니다.
다음과 같이 수정하세요:
val pagerState = rememberPagerState(
initialPage = 0,
- pageCount = { groupCards.size }
+ pageCount = { maxOf(1, groupCards.size) }
)또한 빈 상태 처리를 추가하는 것을 고려해보세요:
+ if (groupCards.isEmpty()) {
+ // Empty state UI
+ return
+ }🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/myPage/groupPage/MyGroupPager.kt around
lines 24 to 27, the pagerState initialization uses groupCards.size directly,
which can cause a crash if the list is empty. Modify the pageCount lambda to
return at least 1 when groupCards.size is 0 to prevent crashes. Additionally,
implement UI logic to handle the empty state gracefully, such as showing a
placeholder or message when there are no group cards.
| var value by rememberSaveable { mutableStateOf("") } | ||
|
|
||
| Box( | ||
| Modifier | ||
| .padding(horizontal = 20.dp) | ||
| .fillMaxWidth() | ||
| .height(48.dp) | ||
| ) { | ||
| OutlinedTextField( | ||
| value = value, | ||
| onValueChange = onValueChange, |
There was a problem hiding this comment.
상태 관리 로직에 문제가 있습니다
onValueChange 콜백이 내부 상태 업데이트와 연결되지 않았습니다.
다음과 같이 수정하세요:
OutlinedTextField(
value = value,
- onValueChange = onValueChange,
+ onValueChange = { newValue ->
+ value = newValue
+ onValueChange(newValue)
+ },📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| var value by rememberSaveable { mutableStateOf("") } | |
| Box( | |
| Modifier | |
| .padding(horizontal = 20.dp) | |
| .fillMaxWidth() | |
| .height(48.dp) | |
| ) { | |
| OutlinedTextField( | |
| value = value, | |
| onValueChange = onValueChange, | |
| var value by rememberSaveable { mutableStateOf("") } | |
| Box( | |
| Modifier | |
| .padding(horizontal = 20.dp) | |
| .fillMaxWidth() | |
| .height(48.dp) | |
| ) { | |
| OutlinedTextField( | |
| value = value, | |
| onValueChange = { newValue -> | |
| value = newValue | |
| onValueChange(newValue) | |
| }, | |
| // ...other parameters... | |
| ) | |
| } |
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/myPage/groupPage/SearchTextField.kt
around lines 33 to 43, the onValueChange callback is not updating the internal
state variable 'value'. Fix this by modifying the onValueChange lambda to update
'value' with the new input and then call the external onValueChange callback,
ensuring the internal state stays in sync with user input.
| val cards = rooms.filter { it.genreIndex == page }.take(3) | ||
| Column( | ||
| verticalArrangement = Arrangement.spacedBy(20.dp), | ||
| modifier = Modifier.fillMaxWidth() | ||
| ) { | ||
| cards.forEach { room -> | ||
| CardItemRoom( | ||
| title = room.title, | ||
| participants = room.participants, | ||
| maxParticipants = room.maxParticipants, | ||
| isRecruiting = room.isRecruiting, | ||
| endDate = room.endDate, | ||
| imageRes = room.imageRes, | ||
| onClick = { onRoomClick(room) }, | ||
| hasBorder = true, // 카드에 테두리 추가 | ||
| ) | ||
| } | ||
| // 카드가 3개보다 적을 때 Spacer를 아래에 추가 | ||
| if (cards.size < 3) { | ||
| Spacer( | ||
| modifier = Modifier | ||
| .weight(1f, fill = true) | ||
| .fillMaxWidth() | ||
| ) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
빈 상태 처리 추가
선택된 장르에 해당하는 룸이 없을 때의 빈 상태 처리가 없습니다. 사용자 경험을 위해 빈 상태 메시지를 표시해야 합니다.
빈 상태 처리를 추가하세요:
} { page ->
val cards = rooms.filter { it.genreIndex == page }.take(3)
+ if (cards.isEmpty()) {
+ Box(
+ modifier = Modifier.fillMaxSize(),
+ contentAlignment = Alignment.Center
+ ) {
+ Text(
+ text = "해당 장르의 모임방이 없습니다",
+ color = colors.Grey01,
+ style = typography.view_m500_s14
+ )
+ }
+ } else {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp),
modifier = Modifier.fillMaxWidth()
) {
// 기존 코드
}
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| val cards = rooms.filter { it.genreIndex == page }.take(3) | |
| Column( | |
| verticalArrangement = Arrangement.spacedBy(20.dp), | |
| modifier = Modifier.fillMaxWidth() | |
| ) { | |
| cards.forEach { room -> | |
| CardItemRoom( | |
| title = room.title, | |
| participants = room.participants, | |
| maxParticipants = room.maxParticipants, | |
| isRecruiting = room.isRecruiting, | |
| endDate = room.endDate, | |
| imageRes = room.imageRes, | |
| onClick = { onRoomClick(room) }, | |
| hasBorder = true, // 카드에 테두리 추가 | |
| ) | |
| } | |
| // 카드가 3개보다 적을 때 Spacer를 아래에 추가 | |
| if (cards.size < 3) { | |
| Spacer( | |
| modifier = Modifier | |
| .weight(1f, fill = true) | |
| .fillMaxWidth() | |
| ) | |
| } | |
| } | |
| } | |
| } { page -> | |
| val cards = rooms.filter { it.genreIndex == page }.take(3) | |
| if (cards.isEmpty()) { | |
| Box( | |
| modifier = Modifier.fillMaxSize(), | |
| contentAlignment = Alignment.Center | |
| ) { | |
| Text( | |
| text = "해당 장르의 모임방이 없습니다", | |
| color = colors.Grey01, | |
| style = typography.view_m500_s14 | |
| ) | |
| } | |
| } else { | |
| Column( | |
| verticalArrangement = Arrangement.spacedBy(20.dp), | |
| modifier = Modifier.fillMaxWidth() | |
| ) { | |
| cards.forEach { room -> | |
| CardItemRoom( | |
| title = room.title, | |
| participants = room.participants, | |
| maxParticipants = room.maxParticipants, | |
| isRecruiting = room.isRecruiting, | |
| endDate = room.endDate, | |
| imageRes = room.imageRes, | |
| onClick = { onRoomClick(room) }, | |
| hasBorder = true, // 카드에 테두리 추가 | |
| ) | |
| } | |
| // 카드가 3개보다 적을 때 Spacer를 아래에 추가 | |
| if (cards.size < 3) { | |
| Spacer( | |
| modifier = Modifier | |
| .weight(1f, fill = true) | |
| .fillMaxWidth() | |
| ) | |
| } | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/myPage/groupPage/DeadlineRoomSection.kt
around lines 96 to 122, there is no handling for the empty state when no rooms
match the selected genre. Add a conditional check for when the filtered rooms
list is empty and display a user-friendly empty state message or UI element in
place of the cards to improve user experience.
| val buttonText = when (buttonType) { | ||
| BottomButtonType.JOIN -> "참여하기" | ||
| BottomButtonType.CANCEL -> "참여 취소하기" | ||
| BottomButtonType.CLOSE -> "모집 마감하기" | ||
| } | ||
| val buttonColor = when (buttonType) { | ||
| BottomButtonType.JOIN -> colors.Purple | ||
| BottomButtonType.CANCEL -> colors.Red | ||
| BottomButtonType.CLOSE -> colors.Grey02 | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
when 표현식의 exhaustive 검사를 고려하세요.
BottomButtonType에 새로운 값이 추가되면 이 when 표현식들이 컴파일 오류를 발생시키지 않을 수 있습니다. sealed class나 enum으로 exhaustive 검사를 보장하는 것이 좋습니다.
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/myPage/groupRoom/GroupRoomScreen.kt
around lines 244 to 253, the when expressions for buttonText and buttonColor are
not exhaustive, risking missing cases if BottomButtonType gains new values. To
fix this, ensure BottomButtonType is defined as a sealed class or enum to enable
exhaustive when checks, and add an else branch or handle all cases explicitly in
the when expressions to guarantee compile-time exhaustiveness.
| _myGroups.value = listOf( | ||
| MyGroupCardData("호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), | ||
| MyGroupCardData("호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1"), | ||
| MyGroupCardData("호르몬 체인지 완독하는 방", 22, R.drawable.bookcover_sample, 40, "uibowl1") | ||
| ) | ||
| _deadlineRooms.value = listOf( | ||
| CardItemRoomData("시집만 읽는 사람들 3월", 22, 30, true, 3, R.drawable.bookcover_sample, 0), // 문학 | ||
| CardItemRoomData("일본 소설 좋아하는 사람들", 22, 30, true, 3, R.drawable.bookcover_sample, 0), // 문학 | ||
| CardItemRoomData("명작 같이 읽기방", 22, 30, true, 3, R.drawable.bookcover_sample, 0), // 문학 | ||
|
|
||
| CardItemRoomData("물리책 읽는 방", 13, 20, true, 1, R.drawable.bookcover_sample, 1), // 과학·IT | ||
| CardItemRoomData("코딩 과학 동아리", 12, 15, true, 5, R.drawable.bookcover_sample, 1), // 과학·IT | ||
|
|
||
| CardItemRoomData("사회과학 인문 탐구", 8, 12, true, 4, R.drawable.bookcover_sample, 2), // 사회과학 | ||
| ) | ||
|
|
||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
하드코딩된 샘플 데이터를 분리하세요.
init 블록에 하드코딩된 샘플 데이터가 있습니다. 실제 구현에서는 Repository 패턴을 사용해야 하므로, 이를 별도 메서드로 분리하거나 테스트용임을 명확히 표시하세요.
// 테스트용 데이터 로딩
private fun loadSampleData() {
_myGroups.value = createSampleGroups()
_deadlineRooms.value = createSampleRooms()
}
init {
// TODO: Replace with actual repository call
loadSampleData()
}🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/myPage/viewModel/MyPageViewModel.kt
between lines 26 and 42, the sample data is hardcoded directly inside the init
block. To improve code organization and clarify that this is test data, extract
the sample data initialization into a separate private method such as
loadSampleData(), and call this method from the init block with a TODO comment
indicating it should be replaced by actual repository calls later.
| if (showLimit) { | ||
| Box( | ||
| modifier = Modifier | ||
| .align(Alignment.CenterEnd) | ||
| .padding(end = 14.dp) | ||
| ) { | ||
| Text( | ||
| text = "${text.length}/$limit", | ||
| color = colors.White, | ||
| style = typography.info_r400_s12_h24 | ||
| ) | ||
| } | ||
| }, | ||
| singleLine = true | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
문자 수 카운터 위치가 겹칠 수 있습니다.
문자 수 표시가 trailingIcon과 겹칠 수 있습니다. showIcon과 showLimit가 모두 true일 때의 레이아웃을 고려해야 합니다.
showIcon = true이고 showLimit = true일 때 UI 요소들이 겹치는 문제가 발생할 수 있습니다. 레이아웃 충돌을 방지하는 로직을 추가하세요.
if (showLimit) {
Box(
modifier = Modifier
.align(Alignment.CenterEnd)
- .padding(end = 14.dp)
+ .padding(end = if (showIcon) 50.dp else 14.dp)
) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (showLimit) { | |
| Box( | |
| modifier = Modifier | |
| .align(Alignment.CenterEnd) | |
| .padding(end = 14.dp) | |
| ) { | |
| Text( | |
| text = "${text.length}/$limit", | |
| color = colors.White, | |
| style = typography.info_r400_s12_h24 | |
| ) | |
| } | |
| }, | |
| singleLine = true | |
| ) | |
| } | |
| } | |
| if (showLimit) { | |
| Box( | |
| modifier = Modifier | |
| .align(Alignment.CenterEnd) | |
| .padding(end = if (showIcon) 50.dp else 14.dp) | |
| ) { | |
| Text( | |
| text = "${text.length}/$limit", | |
| color = colors.White, | |
| style = typography.info_r400_s12_h24 | |
| ) | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/common/forms/FormTextFieldDefault.kt
around lines 91 to 104, the character count display can overlap with the
trailingIcon when both showIcon and showLimit are true. To fix this, add layout
logic that adjusts the position or spacing of the character count when showIcon
is also true, ensuring the two UI elements do not overlap and maintain clear
separation.
There was a problem hiding this comment.
Pull Request Overview
This PR implements the complete UI for the 모임 page, including new screens for group rooms, MyPage modifications, and component adjustments requested for consistency and improved navigation. Key changes include updates to gradle dependency versions and libraries, revisions to string and color resources, and the introduction/refactor of multiple UI components and screens (e.g. GroupRoomScreen, MyGroupScreen, and DeadlineRoomSection).
Reviewed Changes
Copilot reviewed 29 out of 31 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml & build.gradle.kts | Added/updated dependencies (navigation runtime, accompanist pager) |
| app/src/main/res/values/strings.xml | Updated and added string resources |
| Color.kt | Introduced a new color variable (genreColor) |
| Navigation & ViewModel Files | Adjusted navigation target and view model changes |
| Multiple UI components (e.g. GroupRoomScreen, MyGroupScreen, DeadlineRoomSection, FormTextFieldDefault, CardAlarm, OptionChipButton) | Added new screens and refactored UI components for 모임 page implementation |
Files not reviewed (1)
- .idea/deploymentTargetSelector.xml: Language not supported
Comments suppressed due to low confidence (1)
app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt:29
- The internal toggle state was removed in favor of an externally controlled 'isSelected' property. Ensure that the parent components consistently manage the selection state to avoid unexpected behavior.
fun OptionChipButton(
| // 글자수 제한 적용 | ||
| val displayText = if (showLimit && text.length > limit) text.substring(0, limit) else text | ||
|
|
||
| Box(modifier = modifier) { | ||
| OutlinedTextField( | ||
| value = displayText, | ||
| onValueChange = { | ||
| // 글자수 제한 적용 | ||
| text = if (showLimit && it.length > limit) it.substring(0, limit) else it |
There was a problem hiding this comment.
[nitpick] Consider clarifying the character limiting logic in the text field by adding inline comments or refactoring the substring logic into a helper function, which can improve readability and future modifications.
| LaunchedEffect(pagerState.currentPage) { | ||
| if (selectedGenre != pagerState.currentPage) { | ||
| onGenreSelect(pagerState.currentPage) | ||
| } | ||
| } | ||
| LaunchedEffect(selectedGenre) { | ||
| if (pagerState.currentPage != selectedGenre) { |
There was a problem hiding this comment.
[nitpick] Two separate LaunchedEffect blocks are used to synchronize the pager state with the selected genre. It might improve clarity and reduce redundancy by combining these effects into a single synchronization block.
| LaunchedEffect(pagerState.currentPage) { | |
| if (selectedGenre != pagerState.currentPage) { | |
| onGenreSelect(pagerState.currentPage) | |
| } | |
| } | |
| LaunchedEffect(selectedGenre) { | |
| if (pagerState.currentPage != selectedGenre) { | |
| LaunchedEffect(pagerState.currentPage, selectedGenre) { | |
| if (selectedGenre != pagerState.currentPage) { | |
| onGenreSelect(pagerState.currentPage) | |
| } else if (pagerState.currentPage != selectedGenre) { |
Nico1eKim
left a comment
There was a problem hiding this comment.
수고하셨습니당 ~ 패키지 구조는 아직 수정 안된거져?
| } | ||
| Spacer(modifier = Modifier.height(5.dp)) | ||
| Text( | ||
| text = "${endDate}일 뒤 " + if (isRecruiting) "모집 마감" else "종료", |
|
|
||
|
|
||
|
|
||
| @Preview(showBackground = true, backgroundColor = 0xFF000000, widthDp = 360) |
There was a problem hiding this comment.
이거 이렇게 안하고 그냥 preview 안에 ThipTheme 집어넣으면 됩니닷
| LazyColumn( | ||
| Modifier | ||
| .fillMaxSize() | ||
| .padding(bottom = 32.dp), // FAB 공간 확보 | ||
| verticalArrangement = Arrangement.spacedBy(0.dp) | ||
| ) { |
There was a problem hiding this comment.
아래 부분에 크게 반복되는 아이템이 없는거같은데 LazyColumn으로 구현한 이유가 있나여?
There was a problem hiding this comment.
Scroll 되게 하려고 했는디 Column에 ScrollState로 스크롤 가능하게 하는게 더 나은 방법인가요?
There was a problem hiding this comment.
저는 개인적으로 반복되는 것들만 LazyColumn으로 하고 반복되는게 아니면 Column에 ScrollState 하는게 가독성 측면에서 좋다고 생각합니다
LazyColumn으로 하면 item 안에 넣어야해서 읽기 불편한거가타여 근데 이건 개인 선호라서 마음대로 하셔도 될둣?
There was a problem hiding this comment.
ㅇㅎ 그러면 Column에 ScrollState로 통일하는게 좋을듯 하네용
| import com.texthip.thip.ui.theme.ThipTheme.typography | ||
|
|
||
| @Composable | ||
| fun MainSectionHeader(onClick: (() -> Unit)? = null) { |
There was a problem hiding this comment.
해당 페이지에서만 쓰이는거면 페이지 이름이 앞에 들어가면 좋을 것 같아요 ~
| } | ||
| Spacer(Modifier.height(12.dp)) | ||
| Text( | ||
| text = "${detail.members} / ${detail.maxMembers}", |
| color = colors.White | ||
| ) | ||
| Text( | ||
| text = "${detail.daysLeft}일 남음", |
| BottomButtonType.JOIN -> "참여하기" | ||
| BottomButtonType.CANCEL -> "참여 취소하기" | ||
| BottomButtonType.CLOSE -> "모집 마감하기" |
| val recommendations: List<CardItemRoomData> | ||
| ) | ||
|
|
||
| enum class BottomButtonType { JOIN, CANCEL, CLOSE } |
There was a problem hiding this comment.
enum은 다른 파일로 따로 분리하면 더 좋을거같습니당
| val MintSub = Color(0xFF4FD9C0) | ||
| val Orange = Color(0xFFFDB770) | ||
| val OrangeSub = Color(0xFFFF8B17) | ||
| val genreColor = Color(0xFFB5B35D) |
There was a problem hiding this comment.
장르 색상이 아마 장르별로 다르게 설정될거라 이부분은 저희 상의하고 따로 정해봐야할거가타여
JJUYAAA
left a comment
There was a problem hiding this comment.
수고하셨숩니당 〰️〰️ 전체적으로 패키지 구조 수정해주시면 될 것 같아욤
There was a problem hiding this comment.
Modifier 잘 빼주셨는데 50-52줄에 보면 colors 설정이 CardDefaults.cardColors 로 돼있어서 외부에서는 변경할 수가 없네용 마이페이지에서는 해당 컴포넌트가 다른 색상으로 쓰여서요! modifier.background 로 카드 색상 변경 가능하도록 부탁드립니데이
| .fillMaxWidth() | ||
| .background( | ||
| brush = Brush.verticalGradient( | ||
| colors = listOf(colors.Grey03, colors.DarkGrey, colors.Black) |
There was a problem hiding this comment.
오 이거 싱기하네요
근데 피그마상에서보다 더 밝은 느낌이라, 제가 그라데이션 구현한 방식대로 해보니까 쪼금 더 유동적으로 조절해가면서 그라데이션 효과 줄 수 있는 것 같아효 한번 참고해보셔도 좋을 것 같슴다
.background( Brush.verticalGradient( colors = listOf( Grey03.copy(alpha = 0.6f), Color.Black.copy(alpha = 0.5f) ) ) )
There was a problem hiding this comment.
어디 파일 참고하면 되지? 그 캐릭터 선택창인가요?
There was a problem hiding this comment.
요 파일은 원래대로 되돌려주셔야 할 것 같은데유?
회의때 요 컴포넌트에서 버튼 중복선택, 토글처럼 on/off 자유롭게 조절되도록 수정하기로 했고 그부분 제가 확인해봤는데, 기존 코드 (OptionChipButton) 는 선택 여부를 외부에서 상태로 관리할 수 있도록 isFilled와 onClick만 받게끔 돼있어서 중복 선택도 가능하고 토글기능도 있고, 필터링 기능도 구현 가능하게 돼있더라고요! 기존코드로 돌려서 한번 확인해주시면 좋을 것 같습니닷
| modifier: Modifier = Modifier, | ||
| hint: String | ||
| hint: String, | ||
| showLimit: Boolean = false, |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
app/src/main/res/values/strings.xml (1)
56-77: 네이밍 규칙 불일치와 불필요한 따옴표 문제기존 리뷰에서 지적된 문제들이 여전히 남아있습니다:
- 기존 snake_case(예:
reading_user_num)와 새로 추가된 camelCase(예:onGoing) 혼재- 일부 값에 불필요한 따옴표와 공백 포함(예:
"모집 ","장르 ")프로젝트 전반의 일관성을 위해 snake_case로 통일하고 불필요한 문자를 제거해주세요.
🧹 Nitpick comments (5)
app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt (1)
100-204: 프리뷰 데이터가 너무 길어 가독성 저하프리뷰 함수 내에 긴 목 데이터가 인라인으로 포함되어 가독성을 해칩니다. 별도의 함수나 객체로 분리하는 것을 권장합니다.
다음과 같이 분리할 수 있습니다:
+private fun createSampleGroupData() = listOf( + GroupCardItemRoomData( + title = "모임방 이름입니다. 모임방...", + participants = 22, + maxParticipants = 30, + isRecruiting = true, + endDate = 3, + genreIndex = 0 + ), + // ... 나머지 데이터들 +) @Preview() @Composable fun MyGroupListFilterScreenPreview() { ThipTheme { - val dataList = listOf( - GroupCardItemRoomData( - // ... 긴 데이터들 - ) - ) + val dataList = createSampleGroupData() GroupMyScreen(allDataList = dataList) } }app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupRoomScreen.kt (1)
61-61: 배경 이미지 구현 미완료TODO 코멘트가 있어 배경 이미지 추가가 아직 완료되지 않았습니다. 이 부분의 구현 완료가 필요합니다.
배경 이미지 구현을 도와드릴까요? 또는 이를 추적할 이슈를 생성해드릴까요?
app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt (1)
37-40: NavController 파라미터 활용도가 낮습니다NavHostController를 파라미터로 받고 있지만 실제 네비게이션 로직에서 사용하지 않고 있습니다. ViewModel의 콜백 메서드들을 통해 네비게이션이 처리되는 구조라면, 파라미터 제거를 고려하거나 실제 네비게이션 구현 시 활용 방안을 명확히 해야 합니다.
app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt (2)
26-26: @SuppressLint 사용 이유를 명확히 해주세요
@SuppressLint("UnusedBoxWithConstraintsScope")를 사용하고 있는데, BoxWithConstraints의 scope를 실제로 사용하지 않는다면 다른 레이아웃 컴포저블 사용을 고려해보세요.BoxWithConstraints 대신 Box나 Column 사용을 검토해보세요:
-@SuppressLint("UnusedBoxWithConstraintsScope") - BoxWithConstraints( + Box( modifier = Modifier .fillMaxWidth() .height(588.dp), contentAlignment = Alignment.Center ) { - val horizontalPadding = ((maxWidth - cardWidth) / 2).coerceAtLeast(0.dp) + val horizontalPadding = 16.dp // 또는 적절한 고정값
246-252: Preview 데이터에서 하드코딩된 문자열 발견Preview에서 일부 문자열이 하드코딩되어 있습니다. 사용자 rbqks529가 선호하는 방식에 따라 strings.xml로 추출하는 것이 좋겠습니다.
하드코딩된 문자열을 strings.xml로 이동해주세요:
GroupRoomSectionData( - title = "인기 있는 독서 모임방", + title = stringResource(R.string.popular_reading_rooms), rooms = popularRooms, genres = genres ), GroupRoomSectionData( - title = "인플루언서·작가 독서 모임방", + title = stringResource(R.string.influencer_reading_rooms), rooms = influencerRooms, genres = genres )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
app/build.gradle.kts(2 hunks)app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt(2 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardAlarm.kt(5 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoom.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GenreChipRow.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMainCard.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMyRoomFilterRow.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMySectionHeader.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupPager.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupSearchTextField.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/component/SimplePagerIndicator.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupBookData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupBottomButtonType.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardItemRoomData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomSectionData.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupViewModel.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupRoomScreen.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt(1 hunks)app/src/main/java/com/texthip/thip/ui/myPage/MyPageScreen.kt(2 hunks)app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt(1 hunks)app/src/main/res/values/strings.xml(2 hunks)gradle/libs.versions.toml(2 hunks)
✅ Files skipped from review due to trivial changes (12)
- app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupBottomButtonType.kt
- app/src/main/java/com/texthip/thip/ui/myPage/MyPageScreen.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/component/SimplePagerIndicator.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomSectionData.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardData.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupBookData.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/component/GenreChipRow.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupPager.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupCardItemRoomData.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupSearchTextField.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMySectionHeader.kt
- app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupRoomData.kt
🚧 Files skipped from review as they are similar to previous changes (7)
- app/src/main/java/com/texthip/thip/ui/navigator/MainNavHost.kt
- app/build.gradle.kts
- app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt
- app/src/main/java/com/texthip/thip/ui/common/cards/CardAlarm.kt
- app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt
- app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoom.kt
- gradle/libs.versions.toml
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: rbqks529
PR: THIP-TextHip/THIP-Android#30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.961Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.
app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt (1)
Learnt from: rbqks529
PR: THIP-TextHip/THIP-Android#30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.216Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.
app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupViewModel.kt (1)
Learnt from: rbqks529
PR: THIP-TextHip/THIP-Android#30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.216Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.
app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt (1)
Learnt from: rbqks529
PR: THIP-TextHip/THIP-Android#30
File: app/src/main/java/com/texthip/thip/ui/myPage/groupPage/GroupPageScreen.kt:34-37
Timestamp: 2025-07-01T07:19:01.216Z
Learning: GroupPageScreen의 MyPageViewModel은 임시 ViewModel로, 현재는 프로토타입 단계이므로 오류 처리 등의 추가 기능은 나중에 구현 예정입니다.
app/src/main/res/values/strings.xml (1)
Learnt from: rbqks529
PR: THIP-TextHip/THIP-Android#30
File: app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt:108-112
Timestamp: 2025-07-01T07:19:10.961Z
Learning: The user rbqks529 prefers to extract hardcoded UI strings to StringResource files (strings.xml) rather than keeping them inline in Compose components, which is a good practice for maintainability and localization in Android development.
🧬 Code Graph Analysis (2)
app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMyRoomFilterRow.kt (1)
app/src/main/java/com/texthip/thip/ui/common/buttons/OptionChipButton.kt (1)
OptionChipButton(28-80)
app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupRoomScreen.kt (4)
app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt (1)
DefaultTopAppBar(19-62)app/src/main/java/com/texthip/thip/ui/common/cards/CardRoomBook.kt (1)
CardRoomBook(36-139)app/src/main/java/com/texthip/thip/ui/common/cards/CardItemRoomSmall.kt (1)
CardItemRoomSmall(35-118)app/src/main/java/com/texthip/thip/ui/theme/Theme.kt (1)
ThipTheme(41-69)
🔇 Additional comments (9)
app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupMyScreen.kt (1)
35-49: 필터링 로직 잘 구현됨상태 관리와 필터링 로직이 명확하고 올바르게 구현되어 있습니다.
remember를 사용하여 성능 최적화도 잘 되어 있습니다.app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMainCard.kt (1)
41-146: 잘 구성된 카드 컴포넌트그라데이션 배경, 레이아웃 구성, 그리고 상태 관리가 모두 적절하게 구현되어 있습니다.
remember를 사용한 성능 최적화와 StringResource 활용도 좋습니다.app/src/main/java/com/texthip/thip/ui/group/myroom/screen/GroupRoomScreen.kt (1)
254-283: 버튼 상태 관리 잘 구현됨
when표현식을 사용한 버튼 텍스트와 색상 관리가 명확하고 올바르게 구현되어 있습니다. 각 상태에 따른 UI 변화가 적절합니다.app/src/main/java/com/texthip/thip/ui/group/myroom/mock/GroupViewModel.kt (1)
8-90: 프로토타입 단계에 적합한 ViewModel 구현
mock패키지에 위치한 임시 ViewModel로서 현재 구현이 적절합니다.StateFlow사용과 초기 목 데이터 설정이 올바르게 되어 있으며, 빈 스텁 메서드들도 프로토타입 단계에서는 합리적입니다.app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt (3)
41-43: State 수집이 적절히 구현되었습니다ViewModel의 StateFlow들을 collectAsState()로 적절히 수집하여 Compose 상태로 관리하고 있습니다. 상태 호이스팅 패턴을 잘 따르고 있습니다.
80-85: 구분선 구현이 깔끔합니다색상이 있는 Spacer를 사용하여 섹션 구분선을 구현한 방식이 깔끔합니다. UI/UX적으로 적절한 시각적 구분을 제공하고 있습니다.
104-111: Preview 구현이 잘 되어있습니다Preview 컴포저블에서 remember를 사용하여 ViewModel 인스턴스를 생성하고 ThipTheme을 적용한 구현이 적절합니다. UI 개발 시 유용한 미리보기를 제공할 수 있습니다.
app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt (2)
118-125: 빈 공간 처리 로직이 좋습니다카드가 3개 미만일 때 빈 공간을 채우는 로직이 잘 구현되어 있습니다. UI 일관성을 위한 좋은 처리입니다.
101-101: 필터링 로직의 안전성을 검토해주세요
genreIndex == selectedGenre필터링에서 인덱스 범위를 벗어날 가능성이 있습니다. 안전성 검증을 추가하는 것이 좋습니다.안전한 필터링 로직으로 개선해주세요:
- val cards = section.rooms.filter { it.genreIndex == selectedGenre }.take(3) + val cards = section.rooms.filter { + it.genreIndex == selectedGenre && selectedGenre < section.genres.size + }.take(3)Likely an incorrect or invalid review comment.
| fun GroupMyRoomFilterRow( | ||
| selectedStates: BooleanArray, | ||
| onToggle: (Int) -> Unit | ||
| ) { | ||
| Row( | ||
| horizontalArrangement = Arrangement.spacedBy(12.dp) | ||
| ) { | ||
| OptionChipButton( | ||
| text = stringResource(R.string.onGoing), | ||
| isFilled = true, | ||
| onClick = { onToggle(0) } | ||
| ) | ||
| OptionChipButton( | ||
| text = stringResource(R.string.recruiting), | ||
| isFilled = true, | ||
| onClick = { onToggle(1) } | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
선택 상태가 UI에 반영되지 않는 문제
selectedStates 파라미터를 받아오지만 실제로 사용하지 않아서 버튼의 선택 상태가 시각적으로 표시되지 않습니다. OptionChipButton의 isSelected 파라미터를 활용하여 선택 상태를 반영해야 합니다.
다음과 같이 수정하여 선택 상태를 반영하세요:
OptionChipButton(
text = stringResource(R.string.onGoing),
isFilled = true,
+ isSelected = selectedStates[0],
onClick = { onToggle(0) }
)
OptionChipButton(
text = stringResource(R.string.recruiting),
isFilled = true,
+ isSelected = selectedStates[1],
onClick = { onToggle(1) }
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fun GroupMyRoomFilterRow( | |
| selectedStates: BooleanArray, | |
| onToggle: (Int) -> Unit | |
| ) { | |
| Row( | |
| horizontalArrangement = Arrangement.spacedBy(12.dp) | |
| ) { | |
| OptionChipButton( | |
| text = stringResource(R.string.onGoing), | |
| isFilled = true, | |
| onClick = { onToggle(0) } | |
| ) | |
| OptionChipButton( | |
| text = stringResource(R.string.recruiting), | |
| isFilled = true, | |
| onClick = { onToggle(1) } | |
| ) | |
| } | |
| } | |
| fun GroupMyRoomFilterRow( | |
| selectedStates: BooleanArray, | |
| onToggle: (Int) -> Unit | |
| ) { | |
| Row( | |
| horizontalArrangement = Arrangement.spacedBy(12.dp) | |
| ) { | |
| OptionChipButton( | |
| text = stringResource(R.string.onGoing), | |
| isFilled = true, | |
| isSelected = selectedStates[0], | |
| onClick = { onToggle(0) } | |
| ) | |
| OptionChipButton( | |
| text = stringResource(R.string.recruiting), | |
| isFilled = true, | |
| isSelected = selectedStates[1], | |
| onClick = { onToggle(1) } | |
| ) | |
| } | |
| } |
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupMyRoomFilterRow.kt
around lines 12 to 30, the selectedStates parameter is not used, so the UI does
not reflect the selection state of the buttons. To fix this, pass the
corresponding selectedStates value to the isSelected parameter of each
OptionChipButton to visually indicate which button is selected.
| LogoTopAppBar( | ||
| leftIcon = painterResource(R.drawable.ic_done), | ||
| hasNotification = false, | ||
| onLeftClick = { }, | ||
| onRightClick = { } | ||
| ) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
TopAppBar 아이콘 사용법을 검토해주세요
왼쪽 아이콘으로 ic_done을 사용하고 있는데, 일반적으로 done 아이콘은 완료/확인 작업에 사용됩니다. GroupScreen의 맥락에서 적절한 아이콘인지 확인이 필요합니다.
아이콘 사용이 적절한지 확인해주세요:
🏁 Script executed:
#!/bin/bash
# Description: GroupScreen의 topappbar에서 사용하는 아이콘이 적절한지 확인
# 다른 screen들에서 LogoTopAppBar의 leftIcon 사용 패턴 확인
rg -A 3 -B 3 "LogoTopAppBar" --type kotlinLength of output: 3045
TopAppBar 왼쪽 아이콘 교체 검토 필요
LogoTopAppBarPreview 에서는 ic_search 를, 실제 GroupScreen 에서는 ic_done 를 사용 중입니다.
done 아이콘은 완료·확인 액션용이므로, 상단바 왼쪽 내비게이션에는 뒤로가기 아이콘이 더 적합합니다.
- 파일:
app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt - 위치: 56행 (
LogoTopAppBar호출 부분)
제안 수정안:
- LogoTopAppBar(
- leftIcon = painterResource(R.drawable.ic_done),
+ LogoTopAppBar(
+ leftIcon = painterResource(R.drawable.ic_arrow_back), // 뒤로가기 아이콘으로 교체
hasNotification = false,
onLeftClick = { /* navController.popBackStack() 등 뒤로가기 로직 연결 */ },
onRightClick = { }
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| LogoTopAppBar( | |
| leftIcon = painterResource(R.drawable.ic_done), | |
| hasNotification = false, | |
| onLeftClick = { }, | |
| onRightClick = { } | |
| ) | |
| LogoTopAppBar( | |
| leftIcon = painterResource(R.drawable.ic_arrow_back), // 뒤로가기 아이콘으로 교체 | |
| hasNotification = false, | |
| onLeftClick = { /* navController.popBackStack() 등 뒤로가기 로직 연결 */ }, | |
| onRightClick = { } | |
| ) |
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/group/screen/GroupScreen.kt around line
56, the left icon of LogoTopAppBar is set to ic_done, which is more suitable for
confirmation actions. Replace this icon with a back navigation icon such as
ic_back or a similar resource to better represent the expected behavior of the
top app bar's left icon.
| val cardWidth = 320.dp // 카드 폭 원하는 값으로 맞추기! | ||
| val pageSpacing = 12.dp | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
하드코딩된 값들을 상수로 추출해주세요
카드 폭과 페이지 간격이 하드코딩되어 있습니다. 유지보수와 일관성을 위해 상수로 추출하는 것이 좋습니다.
상수를 companion object로 추출해주세요:
+companion object {
+ private val CARD_WIDTH = 320.dp
+ private val PAGE_SPACING = 12.dp
+}
+
- val cardWidth = 320.dp // 카드 폭 원하는 값으로 맞추기!
- val pageSpacing = 12.dp
+ val cardWidth = CARD_WIDTH
+ val pageSpacing = PAGE_SPACINGCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/ui/group/myroom/component/GroupDeadlineRoomSection.kt
around lines 32 to 34, the cardWidth and pageSpacing values are hardcoded. To
improve maintainability and consistency, extract these hardcoded values into
constants inside a companion object within the class. Define cardWidth and
pageSpacing as val constants in the companion object and replace the hardcoded
usages with these constants.
➕ 이슈 링크
🔎 작업 내용
어떤 부분이 구현되었는지 설명해주세요
내 모임방(진행 중, 모집 중)
네비게이션과 연결된 메인 모임 페이지
모임방 페이지(참여, 참여 취소, 모집 마감)
주연이가 부탁한 컴포넌트 수정
📸 스크린샷

**내 모임방 (진행 중)** 내 모임방 (모집 중)

네비게이션과 연결된 메인 모임 페이지

모임방 페이지(참여, 참여 취소, 모집 마감)

컴포넌트 수정

FormTextFieldDefault
CardAlarm

프로젝트 구조

😢 해결하지 못한 과제
모임방 참여 페이지 배경
페이지에서 컴포넌트를 눌렀을 때 click event(화면 연결)
CardAlarm에서 ~시간 전과 날짜를 보여주는 부분은 서버에서 어떻게 데이터를 보내주는지에 따라서 많이 바뀔 것 같아서 검토가 필요할듯 합니당
📢 리뷰어들에게
Summary by CodeRabbit
신규 기능
기능 개선 및 변경
문서화 및 문자열
스타일 및 테마
환경설정 및 라이브러리