-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 마이페이지 개편(parent issue) #778
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마이페이지 UI 컴포넌트를 재구조화하여 MyActivity/MyLibrary 모델을 myPage 패키지 루트로 이동하고, 기존 MyActivityFragment와 MyLibraryFragment를 제거한 후 MyPageFragment로 통합했습니다. 패키지 구조 정리 및 레이아웃 재구성이 포함됩니다. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
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
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. Comment |
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: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityFragment.kt (1)
168-189: 좋아요 토글/카운트 업데이트가 Fragment↔ViewModel 간 의미가 뒤집혀 동작할 가능성이 큽니다(카운트 원복/반대로 저장 위험).
현재 Fragment는 UI를 먼저 토글한 뒤(새 상태)updateActivityLike(view.isSelected, ..., updatedLikeCount)를 호출하고, ViewModel은isLiked를 기준으로saveLike(true/false)와newLikeCount를 다시 계산하고 있어 상호 모순이 납니다.제안 수정(계약을 “클릭 전 상태(wasLiked), 클릭 전 카운트(currentLikeCount)”로 통일)
--- a/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityFragment.kt +++ b/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityFragment.kt @@ override fun onLikeButtonClick( view: View, feedId: Long, ) { val likeCountTextView: TextView = view.findViewById(R.id.tv_my_activity_thumb_up_count) - val currentLikeCount = likeCountTextView.text.toString().toInt() - - val updatedLikeCount: Int = if (view.isSelected) { - if (currentLikeCount > 0) currentLikeCount - 1 else 0 - } else { - currentLikeCount + 1 - } - - likeCountTextView.text = updatedLikeCount.toString() - view.isSelected = !view.isSelected - - otherUserActivityViewModel.updateActivityLike( - view.isSelected, - feedId, - updatedLikeCount, - ) + val wasLiked = view.isSelected + val currentLikeCount = likeCountTextView.text.toString().toIntOrNull() ?: 0 + val targetIsLiked = !wasLiked + val updatedLikeCount = if (targetIsLiked) currentLikeCount + 1 else maxOf(0, currentLikeCount - 1) + + // optimistic UI + likeCountTextView.text = updatedLikeCount.toString() + view.isSelected = targetIsLiked + + // ViewModel에는 "클릭 전 상태/카운트"를 전달 (단일 계약) + otherUserActivityViewModel.updateActivityLike( + wasLiked, + feedId, + currentLikeCount, + ) }app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityViewModel.kt (1)
77-99: 좋아요 저장 파라미터/카운트 계산이 “isLiked 의미”에 강하게 의존합니다 — Fragment와 계약을 명확히 맞추세요.
또한onFailure { }가 비어 있어 optimistic UI를 쓴다면 최소한 롤백/에러 플래그 반영이 필요합니다.제안 diff(“클릭 전 상태 wasLiked” 계약 기준 + 실패 시 상태 반영 예시)
--- a/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityViewModel.kt +++ b/app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityViewModel.kt @@ fun updateActivityLike( - isLiked: Boolean, + wasLiked: Boolean, feedId: Long, currentLikeCount: Int, ) { viewModelScope.launch { runCatching { - if (isLiked) { - feedRepository.saveLike(false, feedId) - } else { - feedRepository.saveLike(true, feedId) - } + val targetIsLiked = !wasLiked + feedRepository.saveLike(targetIsLiked, feedId) }.onSuccess { - val newLikeCount = if (isLiked) currentLikeCount - 1 else currentLikeCount + 1 + val targetIsLiked = !wasLiked + val newLikeCount = + if (targetIsLiked) currentLikeCount + 1 else maxOf(0, currentLikeCount - 1) _otherUserActivityUiState.value = _otherUserActivityUiState.value?.copy( - likeState = ActivityLikeState(feedId, !isLiked, newLikeCount), + likeState = ActivityLikeState(feedId, targetIsLiked, newLikeCount), ) - - saveActivityLikeState(feedId, !isLiked, newLikeCount) + saveActivityLikeState(feedId, targetIsLiked, newLikeCount) }.onFailure { + _otherUserActivityUiState.value = _otherUserActivityUiState.value?.copy(error = true) } } }app/src/main/java/com/into/websoso/ui/activityDetail/ActivityDetailActivity.kt (2)
234-247: (중요) showPopupMenu가 항상 OtherUser 팝업만 inflate 함 — MY_ACTIVITY 메뉴가 동작 불가
현재MenuOtherUserActivityPopupBinding.inflate()로 고정되어MenuMyActivityPopupBinding분기가 사실상 도달 불가능합니다(수정/삭제 메뉴 미노출, 리포트 메뉴만 노출 위험).Proposed fix (source에 따라 inflate 분기)
private fun showPopupMenu( view: View, feedId: Long, ) { val inflater = LayoutInflater.from(this) - val binding = MenuOtherUserActivityPopupBinding.inflate(inflater) + val binding: ViewDataBinding = + when (activityDetailViewModel.source) { + SOURCE_MY_ACTIVITY -> MenuMyActivityPopupBinding.inflate(inflater) + SOURCE_OTHER_USER_ACTIVITY -> MenuOtherUserActivityPopupBinding.inflate(inflater) + else -> MenuOtherUserActivityPopupBinding.inflate(inflater) + } _popupWindow?.dismiss() _popupWindow = PopupWindow(binding.root, WRAP_CONTENT, WRAP_CONTENT, true).apply { elevation = 2f showAsDropDown(view) } setupPopupMenuClickListeners(binding, feedId) }Also applies to: 249-276
203-224: 좋아요 카운트 파싱이 toInt() 고정 — 비정상 텍스트/공백에서 크래시 가능
TextView.text가 숫자가 아닐 경우toInt()가 예외를 던질 수 있어toIntOrNull()방어가 안전합니다.Proposed fix (toIntOrNull + 기본값)
val likeCountTextView: TextView = view.findViewById(tv_my_activity_thumb_up_count) -val currentLikeCount = likeCountTextView.text.toString().toInt() +val currentLikeCount = likeCountTextView.text.toString().toIntOrNull() ?: 0
🤖 Fix all issues with AI agents
In @app/src/main/java/com/into/websoso/ui/main/myPage/MyPageFragment.kt:
- Around line 275-303: updateNovelPreferencesKeywords currently only adds new
chips and never removes or updates existing ones, causing stale chips when
counts drop or names change; modify updateNovelPreferencesKeywords to fully
re-render the chip container by clearing binding.wcgMyLibraryAttractivePoints
(removeAllViews or equivalent) before iterating novelPreferences.keywords and
then add createKeywordChip(...) for each keyword (or alternatively compute the
set difference and remove only obsolete children), ensuring the UI reflects the
current novelPreferences.keywords exactly.
In @app/src/main/res/layout/fragment_my_page.xml:
- Around line 261-270: The layout TextView with id
tv_my_linear_storage_quit_title references a possibly misspelled string resource
my_library_quite; verify intended text and if it should be "quit" rename the
string resource key to my_library_quit (and update all usages) or correct the
TextView to use the existing, correctly spelled key; ensure resource name and
value/usage are consistent across the project.
- Around line 58-67: Clickable ImageView(s) like iv_my_page_sticky_go_to_setting
are missing contentDescription which breaks accessibility and lint; add
android:contentDescription="@string/..." to the ImageView(s) and create
corresponding entries in strings.xml (e.g., "settings", "toggle_notifications"
or similar descriptive labels) so TalkBack announces the purpose; apply the same
change to the other clickable ImageView(s) referenced around lines 434-444.
- Around line 521-553: The ConstraintLayout with id
cl_my_library_attractive_points uses layout_height="0dp" but only has a top
constraint, which can collapse its height; fix by either changing
cl_my_library_attractive_points to layout_height="wrap_content" or add a proper
bottom constraint (for example constrain its bottom to the top of
wcg_my_library_attractive_points or to parent) so the view can measure correctly
and the contained TextView (tv_my_library_attractive_points) remains visible.
- Around line 277-290: The divider View and the ConstraintLayout
cl_my_library_genre_preference both use
app:layout_constraintTop_toBottomOf="@id/cl_my_page_user_profile", causing
overlap; give the View a unique id (e.g., @+id/divider_my_page) and change
cl_my_library_genre_preference's top constraint to
app:layout_constraintTop_toBottomOf="@id/divider_my_page" so the section is
positioned below the divider instead of the same anchor.
🧹 Nitpick comments (7)
app/src/main/res/drawable/btn_profile_edit.xml (1)
1-14: 드로어블 구현은 올바르나, 색상 리소스 사용을 권장합니다.벡터 드로어블이 올바르게 정의되었으며 프로필 수정 버튼으로 적절해 보입니다. 다만 하드코딩된 색상 값(
#ffffff,#DDDDE3,#949399) 대신 색상 리소스(@color/...)를 사용하면 테마 지원과 유지보수성이 향상됩니다.♻️ 색상 리소스를 사용한 개선안
먼저
res/values/colors.xml에 색상을 정의하세요:<color name="profile_edit_background">#FFFFFF</color> <color name="profile_edit_stroke">#DDDDE3</color> <color name="profile_edit_icon">#949399</color>그런 다음 드로어블에서 색상 리소스를 참조하세요:
<path android:strokeWidth="1" android:pathData="M13.481,0.5C20.608,0.5 26.5,6.378 26.5,13.494C26.5,20.621 20.621,26.5 13.494,26.5C6.379,26.5 0.5,20.621 0.5,13.494C0.5,6.38 6.366,0.5 13.481,0.5Z" - android:fillColor="#ffffff" - android:strokeColor="#DDDDE3"/> + android:fillColor="@color/profile_edit_background" + android:strokeColor="@color/profile_edit_stroke"/> <path android:pathData="M18.208,11.335L19.62,9.925C20.319,9.221 20.345,8.451 19.711,7.799L19.205,7.277C18.571,6.637 17.781,6.703 17.095,7.394L15.683,8.79L18.208,11.335ZM10.644,18.926L17.485,12.032L14.973,9.514L8.131,16.381L6.862,19.461C6.72,19.852 7.121,20.283 7.51,20.139L10.644,18.926Z" - android:fillColor="#949399"/> + android:fillColor="@color/profile_edit_icon"/>app/src/main/java/com/into/websoso/ui/main/myPage/model/AttrativePoints.kt (1)
1-16: 파일명 오타(AttrativePoints.kt)는 정리 권장
클래스명이AttractivePoints라서 파일명도AttractivePoints.kt로 맞추는 편이 좋습니다.app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityFragment.kt (1)
23-26: 패키지 이동 반영은 OK인데,otherUserPage가myPage타입에 직접 의존하는 결합도가 커졌습니다.
가능하면ActivityItemClickListener,UserProfileModel같은 “공유 UI 모델/리스너”는 feature 공통 모듈(또는ui.model성격의 패키지)로 분리하는 쪽이 장기 유지보수에 안전합니다.app/src/main/java/com/into/websoso/ui/mapper/UserMapper.kt (1)
17-22:MyProfileModel.toUi(): UserProfileModelvsMyProfileEntity.toUserProfileModel()가 역할/네이밍이 겹쳐 혼란 소지가 있습니다.
한쪽으로 통일(예:toUserProfileModel()만 유지)하거나toUi()네이밍을 더 구체화하는 정리가 있으면 좋겠습니다.Also applies to: 31-35
app/src/main/java/com/into/websoso/ui/main/myPage/MyLibraryViewModel.kt (1)
116-119:AttractivePoints.Companion.fromString(...)는 불필요하게 장황합니다(가능하면AttractivePoints.fromString(...)로).제안 diff
- AttractivePoints.Companion.fromString(point)?.korean + AttractivePoints.fromString(point)?.koreanapp/src/main/java/com/into/websoso/ui/main/myPage/MyPageFragment.kt (2)
129-192: 로딩/에러 뷰(wllMyPage)를 두 observer가 동시에 제어 — 상태 덮어쓰기/깜빡임 위험
myPageViewModel.uiState와myLibraryViewModel.uiState가 같은 로딩/에러 레이아웃을 각각 토글해서, 한쪽이 “정상”이어도 다른쪽이 “로딩”이면 UI가 흔들릴 수 있습니다(특히 네트워크 타이밍). “최종 표시 상태”를 한 곳에서 합성해서 결정하는 방식이 안전합니다.Also applies to: 203-220
349-358: FragmentResult key가 하드코딩 문자열 — 상수화 권장(오타/호환성 리스크)
"NAVIGATE_TO_LIBRARY_FRAGMENT"는 동일 키를 쓰는 쪽과 함께const val로 공유하는 편이 안전합니다.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (39)
app/src/main/java/com/into/websoso/data/mapper/UserMapper.ktapp/src/main/java/com/into/websoso/ui/activityDetail/ActivityDetailActivity.ktapp/src/main/java/com/into/websoso/ui/activityDetail/ActivityDetailViewModel.ktapp/src/main/java/com/into/websoso/ui/activityDetail/adapter/ActivityDetailAdapter.ktapp/src/main/java/com/into/websoso/ui/activityDetail/adapter/ActivityDetailViewHolder.ktapp/src/main/java/com/into/websoso/ui/activityDetail/model/ActivityDetailUiState.ktapp/src/main/java/com/into/websoso/ui/main/myPage/ActivityItemClickListener.ktapp/src/main/java/com/into/websoso/ui/main/myPage/MyLibraryViewModel.ktapp/src/main/java/com/into/websoso/ui/main/myPage/MyPageFragment.ktapp/src/main/java/com/into/websoso/ui/main/myPage/adapter/MyPageViewPagerAdapter.ktapp/src/main/java/com/into/websoso/ui/main/myPage/adapter/RestGenrePreferenceAdapter.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/ActivitiesModel.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/ActivityLikeState.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/AttrativePoints.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/Genres.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/MyActivityUiState.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/MyLibraryUiState.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/UserActivityModel.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/UserProfileModel.ktapp/src/main/java/com/into/websoso/ui/main/myPage/myActivity/MyActivityFragment.ktapp/src/main/java/com/into/websoso/ui/main/myPage/myActivity/MyActivityViewModel.ktapp/src/main/java/com/into/websoso/ui/main/myPage/myActivity/adapter/MyActivityAdapter.ktapp/src/main/java/com/into/websoso/ui/main/myPage/myActivity/adapter/MyActivityViewHolder.ktapp/src/main/java/com/into/websoso/ui/main/myPage/myActivity/model/UserActivityModel.ktapp/src/main/java/com/into/websoso/ui/main/myPage/myLibrary/MyLibraryFragment.ktapp/src/main/java/com/into/websoso/ui/mapper/ActivityMapper.ktapp/src/main/java/com/into/websoso/ui/mapper/UserMapper.ktapp/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityFragment.ktapp/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityViewModel.ktapp/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/adapter/OtherUserActivityAdapter.ktapp/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/adapter/OtherUserActivityViewHolder.ktapp/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/model/OtherUserActivityUiState.ktapp/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryViewModel.ktapp/src/main/res/drawable/btn_profile_edit.xmlapp/src/main/res/layout/fragment_my_activity.xmlapp/src/main/res/layout/fragment_my_library.xmlapp/src/main/res/layout/fragment_my_page.xmlapp/src/main/res/layout/item_my_activity.xmlcore/resource/src/main/res/values/strings.xml
💤 Files with no reviewable changes (9)
- app/src/main/java/com/into/websoso/ui/main/myPage/myActivity/adapter/MyActivityAdapter.kt
- app/src/main/java/com/into/websoso/ui/main/myPage/myActivity/model/UserActivityModel.kt
- app/src/main/java/com/into/websoso/ui/main/myPage/adapter/MyPageViewPagerAdapter.kt
- app/src/main/res/layout/fragment_my_activity.xml
- app/src/main/java/com/into/websoso/ui/main/myPage/myActivity/MyActivityFragment.kt
- app/src/main/res/layout/fragment_my_library.xml
- app/src/main/java/com/into/websoso/ui/main/myPage/myActivity/adapter/MyActivityViewHolder.kt
- app/src/main/java/com/into/websoso/ui/main/myPage/myLibrary/MyLibraryFragment.kt
- app/src/main/java/com/into/websoso/ui/main/myPage/myActivity/MyActivityViewModel.kt
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/into/websoso/ui/main/myPage/MyPageFragment.kt (1)
app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryFragment.kt (6)
onStorageButtonClick(210-222)updateRestGenrePreferenceVisibility(128-133)updateNovelPreferencesKeywords(182-186)updateDominantGenres(198-208)applyTextColors(135-180)createKeywordChip(188-196)
🔇 Additional comments (29)
app/src/main/java/com/into/websoso/data/mapper/UserMapper.kt (1)
26-26: 패키지 재구성이 정확하게 완료되었습니다.
Genres클래스의 import 경로가 올바르게 업데이트되었고, 파일 내에서 적절하게 사용되고 있습니다. 코드베이스에 이전 패키지 경로 참조가 남아있지 않습니다.app/src/main/java/com/into/websoso/ui/main/myPage/model/Genres.kt (2)
1-1: 패키지 이동이 일관되게 적용되었습니다.다른 모델 클래스들과 함께
myPage.model로 통합되어 구조가 개선되었습니다.
19-24: 코드 간소화가 적절합니다.
Genres.entries를entries로 변경한 것은 올바른 개선입니다. companion object 스코프 내에서 명시적인Genres.접두사는 불필요하므로 코드가 더 간결해졌습니다.app/src/main/java/com/into/websoso/ui/main/myPage/ActivityItemClickListener.kt (1)
1-1: 패키지 단순화가 완료되었습니다.인터페이스를
myActivity서브패키지에서myPage로 이동한 변경사항을 검증했습니다. 모든 의존 파일(6개 어댑터 및 뷰홀더)에서 새 패키지 경로로 import가 일관되게 업데이트되었으며, 이전 패키지 경로에 대한 참조는 남아있지 않습니다.app/src/main/java/com/into/websoso/ui/main/myPage/adapter/RestGenrePreferenceAdapter.kt (1)
1-1: 패키지 재구성이 일관성 있게 적용되었는지 확인이 필요합니다.
myLibrary.adapter에서myPage.adapter로의 이동이 전체 리팩토링 계획과 일치하는지 검증하기 위해, MyPageFragment 및 관련 ViewModel에서 이 어댑터의 import 경로가 올바르게 업데이트되었는지 반드시 확인하세요. 특히 다음을 검증하시기 바랍니다:
- 이전 패키지 경로(
com.into.websoso.ui.main.myPage.myLibrary.adapter.RestGenrePreferenceAdapter)에 대한 참조가 모두 제거되었는지 확인- 새 패키지 경로(
com.into.websoso.ui.main.myPage.adapter.RestGenrePreferenceAdapter)로의 import 업데이트 확인- RestGenrePreferenceAdapter를 사용하는 모든 파일에서 import 문이 정확하게 업데이트되었는지 확인
app/src/main/java/com/into/websoso/ui/main/myPage/model/ActivitiesModel.kt (1)
1-1: 패키지 구조 개선이 적절합니다.
myActivity.model에서myPage.model로의 패키지 이동은 구조를 더 평탄하게 만들어 유지보수성을 향상시킵니다. 코드베이스 전체에서 모든 import 참조가 새 패키지 경로(com.into.websoso.ui.main.myPage.model)로 일관되게 업데이트되었습니다.app/src/main/java/com/into/websoso/ui/main/myPage/model/ActivityLikeState.kt (1)
1-1: ActivityLikeState의 패키지 이동이 올바르게 완료되었습니다.
myPage.model패키지로의 이동 후 모든 의존 파일의 import가 정확하게 업데이트되었습니다:
ActivityDetailViewModel.kt- 올바른 import ✓OtherUserActivityViewModel.kt- 올바른 import ✓OtherUserActivityUiState.kt- 올바른 import ✓이전 패키지 경로에 대한 참조는 남아있지 않습니다. 모델 구조 통합이 적절하게 진행되었습니다.
app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/adapter/OtherUserActivityViewHolder.kt (1)
8-9: LGTM! Import 경로 업데이트가 올바르게 적용되었습니다.패키지 리팩토링에 맞춰 import 경로가 정확하게 수정되었고, ViewHolder의 로직은 변경사항이 없어 기존 동작이 유지됩니다.
app/src/main/java/com/into/websoso/ui/main/myPage/model/MyActivityUiState.kt (1)
1-3: 패키지 및 import 경로가 올바르게 업데이트되었습니다.UI 상태 클래스의 로직 변경 없이 패키지 구조만 깔끔하게 정리되었습니다.
app/src/main/java/com/into/websoso/ui/main/myPage/model/MyLibraryUiState.kt (2)
1-1: 패키지 경로가 올바르게 업데이트되었습니다.중앙 집중식 모델 패키지로의 이동이 일관되게 적용되었습니다.
16-19: 계산 프로퍼티 구현이 올바르게 작동합니다.
totalBadgeCount는topGenres와restGenres목록의 모든 배지 수를 정확하게 합산하며,MyPageFragment.kt의 184번 줄에서updateGenreBadgeTitle()메서드에 올바르게 전달되고 있습니다. 계산 프로퍼티로 구현되어 있어 접근 시마다 재계산되는데, 장르 목록의 크기가 일반적으로 작으므로 성능 영향은 무시할 수 있습니다.app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/model/OtherUserActivityUiState.kt (1)
3-4: LGTM! Import 경로가 새로운 패키지 구조에 맞게 업데이트되었습니다.패키지 리팩토링에 따른 일관된 변경사항이며, UI 상태 클래스의 동작에는 영향이 없습니다.
app/src/main/java/com/into/websoso/ui/main/myPage/model/UserProfileModel.kt (1)
1-1: 모든 import 참조가 업데이트되었는지 수동 검증 필요합니다.패키지 리팩토링이 적용되었으나, 다음 항목들을 확인해야 합니다:
- 이전 패키지 경로
com.into.websoso.ui.main.myPage.myActivity.model.UserProfileModel을 참조하는 import 남아있는지 확인com.into.websoso.ui.main.myPage.model.UserProfileModel로 모든 import이 업데이트되었는지 확인- 특히
build.gradle, 의존성 설정, 테스트 코드에서도 참조 확인코드 컴파일 시 누락된 import 관련 오류가 없으면 완전한 마이그레이션으로 판단할 수 있습니다.
app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserLibrary/OtherUserLibraryViewModel.kt (1)
7-10: 모델 패키지 이동에 따른 import 정리 OK
패키지 리오그 후 누락된 참조가 없는지만assembleDebug/CI로 확인되면 충분해 보입니다.app/src/main/java/com/into/websoso/ui/activityDetail/ActivityDetailViewModel.kt (1)
10-14: import 경로 변경 반영 OK
모델 통합 패키지로의 이동 의도에 맞게 잘 맞춰졌습니다.app/src/main/java/com/into/websoso/ui/mapper/ActivityMapper.kt (1)
3-6: import 경로 변경만 반영된 점 확인 (LGTM)
매핑 로직은 그대로라 리스크가 낮습니다.app/src/main/res/layout/fragment_my_page.xml (1)
6-16: 마이라이브러리ViewModel 바인딩은 정상적으로 설정됨
Fragment에서bindViewModel()메서드(라인 89-93)를 통해myLibraryViewModel과lifecycleOwner가 모두 제대로 연결되어 있습니다. 레이아웃에서의 참조는 런타임 문제를 일으키지 않습니다.Likely an incorrect or invalid review comment.
app/src/main/java/com/into/websoso/ui/mapper/UserMapper.kt (1)
6-6: 모델 패키지 이동(import) 반영은 문제 없어 보입니다.app/src/main/java/com/into/websoso/ui/main/myPage/MyLibraryViewModel.kt (1)
1-10: 패키지/모델 import 정리는 PR 목표(구조 재정리)와 일관됩니다.app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/OtherUserActivityViewModel.kt (1)
9-9: 모델 패키지 이동(import) 반영은 OK입니다.app/src/main/java/com/into/websoso/ui/activityDetail/model/ActivityDetailUiState.kt (1)
3-3: 모델 패키지 이동(import)만 반영되어 있고,UiState구조 변경은 없어 보여 안전합니다.app/src/main/java/com/into/websoso/ui/main/myPage/model/UserActivityModel.kt (1)
1-8: LGTM!새로운 패키지 위치에 모델 클래스가 적절하게 정의되었습니다. 데이터 클래스 구조가 간결하고 명확합니다.
app/src/main/java/com/into/websoso/ui/activityDetail/adapter/ActivityDetailAdapter.kt (1)
8-9: LGTM!import 경로 변경이 다른 파일들과 일관되게 적용되었습니다.
app/src/main/java/com/into/websoso/ui/otherUserPage/otherUserActivity/adapter/OtherUserActivityAdapter.kt (1)
8-9: LGTM!import 경로 변경이 일관되게 적용되었습니다.
core/resource/src/main/res/values/strings.xml (1)
218-219: 새로운 문자열 리소스가 올바르게 추가되고 삭제된 리소스는 깨끗하게 제거되었습니다.마이페이지 개편에 맞춰 추가된
my_page_taste_title과my_page_badge문자열이 레이아웃 및 코드에서 모두 올바르게 사용되고 있으며, 삭제된my_page_library와my_page_activity는 코드베이스 어디에서도 참조되지 않습니다. 특히my_page_badge의%d플레이스홀더가MyPageFragment.kt에서 올바른 파라미터와 함께 처리되고 있습니다.app/src/main/java/com/into/websoso/ui/activityDetail/adapter/ActivityDetailViewHolder.kt (1)
8-9: 패키지 구조 재정리가 올바르게 적용되었습니다.이전
com.into.websoso.ui.main.myPage.myActivity및com.into.websoso.ui.main.myPage.myActivity.model패키지 경로의 import가 코드베이스 전체에서 완전히 제거되었으며, 새로운 import 경로로 정상 변경되었습니다.app/src/main/res/layout/item_my_activity.xml (1)
10-20: 데이터바인딩 타입 경로 변경 반영 OK (패키지 이동 대응)
XML 변수 타입들이com.into.websoso.ui.main.myPage.model및com.into.websoso.ui.main.myPage로 일관되게 갱신되어 리팩터링 목적에 맞습니다.app/src/main/java/com/into/websoso/ui/activityDetail/ActivityDetailActivity.kt (2)
111-113: 타이틀이 항상 other_user_page_activity로 고정됨 — source별 분기 필요 여부 확인
SOURCE_MY_ACTIVITY로 진입하는 경우에도 동일 타이틀이 의도인지 확인이 필요합니다.
165-182: getUserProfile()에 else 추가는 방어적으로 좋음
source미지정/추가 케이스에서 NPE 대신 null로 안전하게 떨어지도록 한 점은 좋습니다.
| private fun updateNovelPreferencesKeywords(novelPreferences: NovelPreferenceEntity) { | ||
| val existingKeywords = mutableSetOf<String>() | ||
|
|
||
| for (i in 0 until binding.wcgMyLibraryAttractivePoints.childCount) { | ||
| val chip = binding.wcgMyLibraryAttractivePoints.getChildAt(i) as? Chip | ||
| chip?.text?.let { existingKeywords.add(it.toString()) } | ||
| } | ||
|
|
||
| novelPreferences.keywords.forEach { keyword -> | ||
| val keywordText = "${keyword.keywordName} ${keyword.keywordCount}" | ||
| if (!existingKeywords.contains(keywordText)) { | ||
| binding.wcgMyLibraryAttractivePoints.addView(createKeywordChip(keyword)) | ||
| existingKeywords.add(keywordText) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private fun createKeywordChip(data: NovelPreferenceEntity.KeywordEntity): Chip = | ||
| WebsosoChip(requireContext()).apply { | ||
| text = "${data.keywordName} ${data.keywordCount}" | ||
| isCheckable = false | ||
| isChecked = false | ||
| isEnabled = false | ||
|
|
||
| setChipBackgroundColorResource(primary_50_F1EFFF) | ||
| setTextColor(ContextCompat.getColor(requireContext(), primary_100_6A5DFD)) | ||
| setTextAppearance(body2) | ||
| } | ||
|
|
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.
키워드 칩 업데이트가 ‘추가만’ 됨 — 감소/변경 시 오래된 칩이 남을 수 있음
existingKeywords로 중복 추가는 막지만, 키워드 수가 줄거나 keywordCount가 변하면 기존 칩이 그대로 남아 UI가 누적/불일치할 수 있습니다.
Proposed fix (현재 상태로 재렌더링; 가장 단순/안전)
private fun updateNovelPreferencesKeywords(novelPreferences: NovelPreferenceEntity) {
- val existingKeywords = mutableSetOf<String>()
-
- for (i in 0 until binding.wcgMyLibraryAttractivePoints.childCount) {
- val chip = binding.wcgMyLibraryAttractivePoints.getChildAt(i) as? Chip
- chip?.text?.let { existingKeywords.add(it.toString()) }
- }
-
- novelPreferences.keywords.forEach { keyword ->
- val keywordText = "${keyword.keywordName} ${keyword.keywordCount}"
- if (!existingKeywords.contains(keywordText)) {
- binding.wcgMyLibraryAttractivePoints.addView(createKeywordChip(keyword))
- existingKeywords.add(keywordText)
- }
- }
+ binding.wcgMyLibraryAttractivePoints.removeAllViews()
+ novelPreferences.keywords.forEach { keyword ->
+ binding.wcgMyLibraryAttractivePoints.addView(createKeywordChip(keyword))
+ }
}🤖 Prompt for AI Agents
In @app/src/main/java/com/into/websoso/ui/main/myPage/MyPageFragment.kt around
lines 275 - 303, updateNovelPreferencesKeywords currently only adds new chips
and never removes or updates existing ones, causing stale chips when counts drop
or names change; modify updateNovelPreferencesKeywords to fully re-render the
chip container by clearing binding.wcgMyLibraryAttractivePoints (removeAllViews
or equivalent) before iterating novelPreferences.keywords and then add
createKeywordChip(...) for each keyword (or alternatively compute the set
difference and remove only obsolete children), ensuring the UI reflects the
current novelPreferences.keywords exactly.
| <ImageView | ||
| android:id="@+id/iv_my_page_sticky_go_to_setting" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginEnd="12dp" | ||
| android:padding="10dp" | ||
| android:src="@drawable/ic_settings" | ||
| app:layout_constraintBottom_toBottomOf="parent" | ||
| app:layout_constraintEnd_toEndOf="parent" | ||
| app:layout_constraintTop_toTopOf="parent" /> |
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.
클릭 가능한 ImageView에 contentDescription 누락 (접근성/린트)
설정 아이콘, 토글 아이콘은 사용자 액션 요소라 contentDescription이 필요합니다(특히 TalkBack).
Proposed fix (문구는 리소스 추가 권장)
<ImageView
android:id="@+id/iv_my_page_sticky_go_to_setting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:contentDescription="@string/a11y_go_to_settings"
android:layout_marginEnd="12dp"
android:padding="10dp"
android:src="@drawable/ic_settings"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_my_library_genre_preference_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:contentDescription="@string/a11y_toggle_genre_list"
android:layout_marginTop="12dp"
android:onClick="@{() -> myLibraryViewModel.updateToggleGenresVisibility()}"
android:padding="20dp"
android:src="@{myLibraryViewModel.uiState.isGenreListVisible ? @drawable/ic_my_library_upper_path : @drawable/ic_my_library_lower_path}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/lv_my_library_rest_genre" />Also applies to: 434-444
🤖 Prompt for AI Agents
In @app/src/main/res/layout/fragment_my_page.xml around lines 58 - 67, Clickable
ImageView(s) like iv_my_page_sticky_go_to_setting are missing contentDescription
which breaks accessibility and lint; add
android:contentDescription="@string/..." to the ImageView(s) and create
corresponding entries in strings.xml (e.g., "settings", "toggle_notifications"
or similar descriptive labels) so TalkBack announces the purpose; apply the same
change to the other clickable ImageView(s) referenced around lines 434-444.
| <TextView | ||
| android:id="@+id/tv_my_linear_storage_quit_title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="2dp" | ||
| android:layout_weight="1" | ||
| android:text="@string/my_library_quite" | ||
| android:textAppearance="@style/body5" | ||
| android:textColor="@color/black" /> | ||
|
|
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.
문자열 리소스 키 my_library_quite 오타 가능성 확인
의도한 값이 “quit”라면 리소스/표기 일관성을 위해 확인이 필요합니다.
🤖 Prompt for AI Agents
In @app/src/main/res/layout/fragment_my_page.xml around lines 261 - 270, The
layout TextView with id tv_my_linear_storage_quit_title references a possibly
misspelled string resource my_library_quite; verify intended text and if it
should be "quit" rename the string resource key to my_library_quit (and update
all usages) or correct the TextView to use the existing, correctly spelled key;
ensure resource name and value/usage are consistent across the project.
| <View | ||
| android:layout_width="0dp" | ||
| android:layout_height="3dp" | ||
| android:background="@color/gray_50_F4F5F8" | ||
| app:layout_constraintEnd_toEndOf="parent" | ||
| app:layout_constraintStart_toStartOf="parent" | ||
| app:layout_constraintTop_toBottomOf="@id/cl_my_page_user_profile" /> | ||
|
|
||
| <androidx.constraintlayout.widget.ConstraintLayout | ||
| android:id="@+id/cl_my_library_genre_preference" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="?attr/actionBarSize" | ||
| app:contentInsetStart="0dp" | ||
| app:layout_collapseMode="pin"> | ||
| android:layout_height="wrap_content" | ||
| app:layout_constraintTop_toBottomOf="@id/cl_my_page_user_profile" | ||
| tools:layout_editor_absoluteX="0dp"> |
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.
구분선(View)과 다음 섹션이 같은 Top 제약을 사용해 겹칠 가능성 큼
view(Line 277-283)는 cl_my_page_user_profile 아래에 붙어있는데, 바로 다음 cl_my_library_genre_preference도 동일하게 cl_my_page_user_profile 아래로 제약(Line 289)이라 겹칠 수 있습니다.
Proposed fix
<View
android:layout_width="0dp"
android:layout_height="3dp"
android:background="@color/gray_50_F4F5F8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_my_page_user_profile" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_my_library_genre_preference"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:layout_constraintTop_toBottomOf="@id/cl_my_page_user_profile"
+ app:layout_constraintTop_toBottomOf="@id/view_my_page_novel_preference_divider"
tools:layout_editor_absoluteX="0dp">🤖 Prompt for AI Agents
In @app/src/main/res/layout/fragment_my_page.xml around lines 277 - 290, The
divider View and the ConstraintLayout cl_my_library_genre_preference both use
app:layout_constraintTop_toBottomOf="@id/cl_my_page_user_profile", causing
overlap; give the View a unique id (e.g., @+id/divider_my_page) and change
cl_my_library_genre_preference's top constraint to
app:layout_constraintTop_toBottomOf="@id/divider_my_page" so the section is
positioned below the divider instead of the same anchor.
| <TextView | ||
| android:id="@+id/tv_my_library_dominant_genre_first_title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="12dp" | ||
| android:text="@{myLibraryViewModel.uiState.topGenres[0].genreName}" | ||
| android:textAppearance="@style/title3" | ||
| android:textColor="@color/black" | ||
| tools:text="로판" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/tv_my_library_dominant_genre_first_count" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="2dp" | ||
| android:text='@{String.format(@string/my_library_genre_count, myLibraryViewModel.uiState.topGenres[0].genreCount)}' | ||
| android:textAppearance="@style/body5" | ||
| android:textColor="@color/gray_200_949399" | ||
| tools:text="12편" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/ll_my_library_dominant_genre_second" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:gravity="center" | ||
| android:orientation="vertical"> | ||
|
|
||
| <ImageView | ||
| android:id="@+id/iv_my_library_dominant_genre_second_logo" | ||
| android:layout_width="30dp" | ||
| android:layout_height="37dp" | ||
| tools:src="@drawable/ic_novel_detail_genre_test" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/tv_my_library_dominant_genre_second_title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="12dp" | ||
| android:text="@{myLibraryViewModel.uiState.topGenres[1].genreName}" | ||
| android:textAppearance="@style/title3" | ||
| android:textColor="@color/black" | ||
| tools:text="로판" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/tv_my_library_dominant_genre_second_count" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="2dp" | ||
| android:text='@{String.format(@string/my_library_genre_count, myLibraryViewModel.uiState.topGenres[1].genreCount)}' | ||
| android:textAppearance="@style/body5" | ||
| android:textColor="@color/gray_200_949399" | ||
| tools:text="12편" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/ll_my_library_dominant_genre_third" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:gravity="center" | ||
| android:orientation="vertical"> | ||
|
|
||
| <ImageView | ||
| android:id="@+id/iv_my_library_dominant_genre_third_logo" | ||
| android:layout_width="30dp" | ||
| android:layout_height="37dp" | ||
| tools:src="@drawable/ic_novel_detail_genre_test" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/tv_my_library_dominant_genre_third_title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="12dp" | ||
| android:text="@{myLibraryViewModel.uiState.topGenres[2].genreName}" | ||
| android:textAppearance="@style/title3" | ||
| android:textColor="@color/black" | ||
| tools:text="로판" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/tv_my_library_dominant_genre_third_count" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="2dp" | ||
| android:text='@{String.format(@string/my_library_genre_count, myLibraryViewModel.uiState.topGenres[2].genreCount)}' | ||
| android:textAppearance="@style/body5" | ||
| android:textColor="@color/gray_200_949399" | ||
| tools:text="12편" /> |
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.
DataBinding에서 topGenres[0..2] 직접 인덱싱은 IndexOutOfBounds 위험
선호 장르가 3개 미만인 케이스(신규/데이터 부족)에서 바인딩 평가 중 크래시 날 수 있습니다. “항상 3개 채워서 내려준다”를 보장하거나, XML에서 size 가드/visibility 처리가 필요합니다.
Proposed fix (XML 가드 예시)
-android:text="@{myLibraryViewModel.uiState.topGenres[0].genreName}"
+android:text="@{myLibraryViewModel.uiState.topGenres.size > 0 ? myLibraryViewModel.uiState.topGenres.get(0).genreName : ``}"
-android:text='@{String.format(@string/my_library_genre_count, myLibraryViewModel.uiState.topGenres[0].genreCount)}'
+android:text='@{myLibraryViewModel.uiState.topGenres.size > 0 ? String.format(@string/my_library_genre_count, myLibraryViewModel.uiState.topGenres.get(0).genreCount) : ``}'| <ListView | ||
| android:id="@+id/lv_my_library_rest_genre" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="0dp" | ||
| android:layout_marginHorizontal="40dp" | ||
| android:layout_marginTop="32dp" | ||
| android:divider="@null" | ||
| app:layout_constraintTop_toBottomOf="@id/ll_my_library_dominant_genre" | ||
| tools:layout_editor_absoluteX="40dp" /> | ||
|
|
||
| <ImageView | ||
| android:id="@+id/iv_my_page_sticky_go_to_setting" | ||
| <ImageView | ||
| android:id="@+id/iv_my_library_genre_preference_path" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="12dp" | ||
| android:onClick="@{() -> myLibraryViewModel.updateToggleGenresVisibility()}" | ||
| android:padding="20dp" | ||
| android:src="@{myLibraryViewModel.uiState.isGenreListVisible ? @drawable/ic_my_library_upper_path : @drawable/ic_my_library_lower_path}" | ||
| app:layout_constraintEnd_toEndOf="parent" | ||
| app:layout_constraintStart_toStartOf="parent" | ||
| app:layout_constraintTop_toBottomOf="@id/lv_my_library_rest_genre" /> | ||
|
|
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.
ListView가 0dp 높이 + 단일 제약이라 화면에 안 보일 수 있음 (+ NestedScrollView 안 ListView는 비권장)
현재 lv_my_library_rest_genre는 layout_height="0dp"인데 bottom 제약이 없어 높이가 0으로 계산될 소지가 큽니다. 또한 NestedScrollView 안 ListView는 측정/스크롤 이슈가 자주 나서 RecyclerView 전환을 권장합니다.
Proposed fix (최소한 보이게)
<ListView
android:id="@+id/lv_my_library_rest_genre"
android:layout_width="match_parent"
- android:layout_height="0dp"
+ android:layout_height="wrap_content"
android:layout_marginHorizontal="40dp"
android:layout_marginTop="32dp"
android:divider="@null"
app:layout_constraintTop_toBottomOf="@id/ll_my_library_dominant_genre"
tools:layout_editor_absoluteX="40dp" />| <androidx.constraintlayout.widget.ConstraintLayout | ||
| android:id="@+id/cl_my_library_attractive_points" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="0dp" | ||
| android:layout_marginTop="20dp" | ||
| android:background="@drawable/bg_my_library_gray50_radius_12dp" | ||
| android:paddingVertical="20dp" | ||
| app:layout_constraintEnd_toEndOf="parent" | ||
| app:layout_constraintStart_toStartOf="parent" | ||
| app:layout_constraintTop_toBottomOf="@id/tv_my_library_novel_preference_title"> | ||
|
|
||
| <TextView | ||
| android:id="@+id/tv_my_library_attractive_points" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginEnd="12dp" | ||
| android:padding="10dp" | ||
| android:src="@drawable/ic_settings" | ||
| android:text="@{myLibraryViewModel.attractivePointsText}" | ||
| android:textAppearance="@style/title2" | ||
| android:textColor="@color/gray_300_52515F" | ||
| app:layout_constraintBottom_toBottomOf="parent" | ||
| app:layout_constraintEnd_toEndOf="parent" | ||
| app:layout_constraintTop_toTopOf="parent" /> | ||
| app:layout_constraintStart_toStartOf="parent" | ||
| app:layout_constraintTop_toTopOf="parent" | ||
| tools:text="현캐릭터,소재가 매력적인 작품" /> | ||
|
|
||
| </androidx.constraintlayout.widget.ConstraintLayout> | ||
|
|
||
| </androidx.appcompat.widget.Toolbar> | ||
|
|
||
| </com.google.android.material.appbar.CollapsingToolbarLayout> | ||
| <com.into.websoso.core.common.ui.custom.WebsosoChipGroup | ||
| android:id="@+id/wcg_my_library_attractive_points" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="16dp" | ||
| app:layout_constraintTop_toBottomOf="@id/cl_my_library_attractive_points" /> | ||
|
|
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.
cl_my_library_attractive_points도 0dp 높이 + 단일 제약이라 내용이 0 높이로 사라질 수 있음
layout_height="0dp"는 (보통) top/bottom 제약이 같이 있어야 합니다. 현재는 top만 있어 0으로 수렴할 가능성이 큽니다.
Proposed fix
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_my_library_attractive_points"
android:layout_width="match_parent"
- android:layout_height="0dp"
+ android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/bg_my_library_gray50_radius_12dp"
android:paddingVertical="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_my_library_novel_preference_title">🤖 Prompt for AI Agents
In @app/src/main/res/layout/fragment_my_page.xml around lines 521 - 553, The
ConstraintLayout with id cl_my_library_attractive_points uses
layout_height="0dp" but only has a top constraint, which can collapse its
height; fix by either changing cl_my_library_attractive_points to
layout_height="wrap_content" or add a proper bottom constraint (for example
constrain its bottom to the top of wcg_my_library_attractive_points or to
parent) so the view can measure correctly and the contained TextView
(tv_my_library_attractive_points) remains visible.
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 (1)
app/src/main/java/com/into/websoso/ui/main/myPage/model/AttractivePoints.kt (1)
14-14:values()대신entries를 사용하는 것을 권장합니다.이미 이 파일을 리팩토링하는 김에, Kotlin 1.9부터 권장되는
entries프로퍼티로 업데이트하면 코드를 현대화할 수 있습니다.♻️ 제안하는 수정 사항
- fun fromString(value: String): AttractivePoints? = values().find { it.name.equals(value, ignoreCase = true) } + fun fromString(value: String): AttractivePoints? = entries.find { it.name.equals(value, ignoreCase = true) }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
app/src/main/java/com/into/websoso/ui/main/home/adpater/PopularFeedsAdapter.ktapp/src/main/java/com/into/websoso/ui/main/myPage/model/AttractivePoints.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). (1)
- GitHub Check: build
🔇 Additional comments (2)
app/src/main/java/com/into/websoso/ui/main/myPage/model/AttractivePoints.kt (1)
1-1: 패키지 구조 개선이 적절합니다.모델 클래스를
myPage.model로 중앙 집중화하는 리팩토링이 올바르게 적용되었습니다. AI 요약에 따르면 관련 임포트들도 코드베이스 전체에서 업데이트되어 일관성이 유지되고 있습니다.app/src/main/java/com/into/websoso/ui/main/home/adpater/PopularFeedsAdapter.kt (1)
3-3: 현재 구현은 올바릅니다. 별도의 변경이 필요 없습니다.
PopularFeedEntity는 데이터 클래스이므로 Kotlin에서 자동으로 생성된equals()메서드를 통해==연산자가 모든 필드를 올바르게 비교합니다. DiffUtil의 "DiffUtilEquals" 린트 경고는 적절한equals()구현이 없는 객체에 대해==를 사용할 때 발생하는 경고이지만, 이 경우 데이터 클래스가 올바른 구현을 제공하므로@SuppressLint어노테이션은 정당합니다.인기 피드 리스트는 일반적으로 작은 크기이고, 현재의 간단하고 명확한 구현이 이 목적에 가장 적합합니다.
📌𝘐𝘴𝘴𝘶𝘦𝘴
📎𝘞𝘰𝘳𝘬 𝘋𝘦𝘴𝘤𝘳𝘪𝘱𝘵𝘪𝘰𝘯
📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵
💬𝘛𝘰 𝘙𝘦𝘷𝘪𝘦𝘸𝘦𝘳𝘴
Summary by CodeRabbit
Release Notes
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.