Skip to content

[Feature] 자체 qa#216

Open
ckals413 wants to merge 5 commits into
developfrom
FLT-24-자체-qa

Hidden character warning

The head ref may contain hidden characters: "FLT-24-\uc790\uccb4-qa"
Open

[Feature] 자체 qa#216
ckals413 wants to merge 5 commits into
developfrom
FLT-24-자체-qa

Conversation

@ckals413

@ckals413 ckals413 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

📌 작업 내용

  • 저장한 작품 화면에서 북마크 토글 시 총 개수 즉시 반영
  • 저장한 작품 5개 이하 상태에서 북마크 취소 시 모달 정상 노출
  • 컬렉션 상세에서 북마크 취소 시 플리커 없이 모달만 노출
  • 저장한 작품 아이템 / OTT 버튼 클릭 시 바텀시트 정상 노출 -> api 없이 ottLists 사용
  • My 프로필 저장한 작품 섹션 아이템 클릭 시 바텀시트 정상 노출
  • 북마크 저장/취소 시 토스트 정상 노출
  • 프로필 수정 저장 후 My 화면 복귀 시 닉네임/이미지 자동 갱신

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 콘텐츠 저장 시 최소 제한 초과 안내 모달 추가
    • 프로필 편집 후 프로필 정보 자동 새로고침
    • 콘텐츠 저장/해제 시 토스트 알림 추가
    • 저장된 콘텐츠에서 OTT 목록 표시 개선
  • 버그 수정

    • 콘텐츠 저장 취소 시 북마크 수 계산 로직 개선

@ckals413 ckals413 self-assigned this Jun 18, 2026
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

CollectionDetail에서 북마크 취소 시 최소 제한 초과 예외를 검출해 모달을 표시하도록 ViewModel·Screen을 수정했습니다. SavedContent에 북마크 토글 토스트와 OTT 목록 바텀시트를 추가했으며, 프로필 수정 완료 후 savedStateHandle 기반 콜백 체인으로 ProfileScreen 헤더를 자동 갱신합니다.

Changes

CollectionDetail 북마크 최소 제한 초과 처리

Layer / File(s) Summary
CollectionDetail 북마크 토글 VM 로직 및 사이드이펙트 타입
...collectiondetail/sideeffect/CollectionDetailSideEffect.kt, ...collectiondetail/CollectionDetailViewModel.kt
ToggleContentBookmarkMinLimitExceeded object를 CollectionDetailSideEffect에 추가하고, toggleContentBookmark에서 취소/추가 경로를 분리하며 ContentMinLimitExceeded 예외 시 해당 이벤트를 방출한다. 실패 롤백 카운트 계산도 fallbackContent.bookmarkCount - 1로 단순화된다.
CollectionDetailScreen 제한 초과 모달 렌더링
...collectiondetail/CollectionDetailScreen.kt
showBookmarkRestrictionModal 상태를 추가하고, ToggleContentBookmarkMinLimitExceeded 사이드이펙트 수신 시 OneButtonModal을 표시하며 확인/닫기 시 상태를 해제한다.

SavedContent 북마크 토스트 및 OTT 바텀시트

Layer / File(s) Summary
SavedContentSideEffect 타입 및 ViewModel sideEffect 스트림
...profile/SavedContentSideEffect.kt, ...profile/SavedContentViewModel.kt
SavedContentSideEffect sealed interface와 ToggleBookmarkSuccess(isBookmarked) 데이터 클래스를 신규 정의하고, SavedContentViewModelMutableSharedFlow 기반 sideEffect 스트림을 추가하며 toggleBookmark 성공 시 이벤트를 emit한다.
SavedContentScreen 토스트·OTT 바텀시트 연결
...core/designsystem/component/listView/SavedContentsSection.kt, ...profile/SavedContentScreen.kt
SavedContentRoute에서 sideEffect 스트림을 구독해 저장/취소 토스트를 전환하고, SavedContentScreen에 OTT 바텀시트 상태를 추가하며 SavedContentListonMoreClick 콜백을 통해 아이템별 getOttSimpleListOttListBottomSheet로 연결한다.

프로필 수정 완료 후 ProfileScreen 자동 갱신

Layer / File(s) Summary
EditProfileRoute·Navigation onProfileSaved 콜백 추가
...editprofile/EditProfileScreen.kt, ...editprofile/navigation/EditProfileNavigation.kt
editProfileNavGraphonProfileSaved 콜백 파라미터를 추가하고, EditProfileRoute에서 navigateUp 이벤트 처리 순서를 onProfileSaved() → navigateUp() 순으로 변경한다.
MainNavHost에서 KEY_PROFILE_UPDATED savedStateHandle 기록
...main/MainNavHost.kt
editProfileNavGraphonProfileSaved 람다에서 MainTabRoute.Profile 백스택 엔트리의 savedStateHandleKEY_PROFILE_UPDATED = true를 기록하고, 백스택 없을 시 IllegalArgumentException을 무시한다.
ProfileNavigation·ProfileScreen·ProfileViewModel 갱신 처리
...profile/navigation/ProfileNavigation.kt, ...profile/ProfileScreen.kt, ...profile/ProfileViewModel.kt
ProfileNavigation에서 KEY_PROFILE_UPDATED StateFlow를 구독해 shouldRefreshProfileProfileRoute로 전달하고, ProfileRoute에서 LaunchedEffectreloadUserProfile()을 호출하며, ProfileViewModel에 프로필 헤더만 재조회하는 reloadUserProfile()을 추가한다. OTT 목록 조회도 로컬 조립 방식으로 전환한다.

Sequence Diagram(s)

sequenceDiagram
  participant EditProfile as EditProfileRoute
  participant MainNavHost as MainNavHost
  participant SavedState as SavedStateHandle
  participant ProfileNav as ProfileNavigation
  participant ProfileRoute as ProfileRoute
  participant ProfileVM as ProfileViewModel

  rect rgba(59, 130, 246, 0.5)
    Note over EditProfile,MainNavHost: 프로필 저장 완료
    EditProfile->>MainNavHost: onProfileSaved()
    MainNavHost->>SavedState: KEY_PROFILE_UPDATED = true
  end

  rect rgba(34, 197, 94, 0.5)
    Note over SavedState,ProfileRoute: 갱신 신호 전파
    SavedState-->>ProfileNav: collectAsStateWithLifecycle
    ProfileNav->>ProfileRoute: shouldRefreshProfile = true
  end

  rect rgba(249, 115, 22, 0.5)
    Note over ProfileRoute,ProfileVM: 프로필 헤더 재조회
    ProfileRoute->>ProfileVM: reloadUserProfile()
    ProfileVM-->>ProfileRoute: _uiState.profile 갱신
    ProfileRoute->>ProfileNav: onProfileRefreshed()
    ProfileNav->>SavedState: KEY_PROFILE_UPDATED = false
  end
Loading
sequenceDiagram
  participant Screen as CollectionDetailScreen
  participant VM as CollectionDetailViewModel
  participant Repo as BookmarkRepository

  Screen->>VM: toggleContentBookmark(contentId)
  alt 북마크 취소(!newBookmarkState)
    VM->>VM: 즉시 bookmarkCount-1 상태 갱신
    VM->>Repo: 저장소 토글 실행
    Repo-->>VM: ContentMinLimitExceeded 예외
    VM->>Screen: ToggleContentBookmarkMinLimitExceeded 방출
    Screen->>Screen: OneButtonModal 표시
  else 북마크 추가(newBookmarkState)
    VM->>VM: adjustedBookmarkCount+1 상태 갱신
    VM->>Repo: 디바운스 후 저장소 토글
    Repo-->>VM: 실패 시 fallbackCount-1 롤백
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • imflint/Flint-Android#153: CollectionDetailViewModel.toggleContentBookmarkCollectionDetailSideEffect의 북마크 토글 흐름·이벤트 확장을 동일하게 건드린다.
  • imflint/Flint-Android#210: editProfileNavGraph/EditProfileScreen의 프로필 수정 완료 콜백 및 MainNavHost 후처리 흐름을 직접 공유한다.
  • imflint/Flint-Android#211: 이 PR이 사용하는 BookmarkException.ContentMinLimitExceeded 예외 타입 및 최소 제한 처리 로직의 원천이다.

Suggested labels

Feat ✨, 📱 UI

Suggested reviewers

  • kimjw2003

Poem

🐰 토끼가 북마크를 눌렀더니
제한 초과 모달이 쏙 나타났네!
저장 성공엔 토스트 한 조각 🍞
OTT 목록은 바텀시트로 펼쳐지고
프로필 수정 후엔 자동 새로고침~
콜백 체인 타고 화면이 반짝! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning PR 설명에서 관련 이슈 번호가 누락되었고 스크린샷도 없으며, 작업 내용은 체크박스만 있고 각 항목에 대한 설명이 부족합니다. 이슈 번호(closed #번호)를 명시하고, 각 작업 항목에 대한 상세 설명과 스크린샷을 추가하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive 제목 '[Feature] 자체 qa'는 변경사항의 주요 내용을 구체적으로 설명하지 못하고 너무 모호합니다. 북마크 토글, 모달 표시, 프로필 갱신 등 주요 기능을 반영한 더 구체적인 제목으로 변경하세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch FLT-24-자체-qa

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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt (1)

129-138: 상수를 이용한 매직 넘버 제거 권장

SavedContentScreen에서는 SavedContentUiState.MIN_REQUIRED_COUNT를 사용하여 최소 저장 개수를 표시합니다. 일관성과 유지보수성을 위해 이 화면에서도 동일한 상수를 참조해야 합니다. 현재 하드코딩된 "5개"를 상수로 변경하면 향후 값 변경 시 한 곳에서만 수정하면 됩니다.

♻️ 제안 수정
     if (showBookmarkRestrictionModal) {
         OneButtonModal(
             title = "작품 저장을 취소할 수 없어요",
-            message = "취향 키워드 분석을 위해\n최소 5개의 작품을 저장해주세요",
+            message = "취향 키워드 분석을 위해\n최소 ${SavedContentUiState.MIN_REQUIRED_COUNT}개의 작품을 저장해주세요",
             buttonText = "확인",
             onConfirm = { showBookmarkRestrictionModal = false },
             onDismiss = { showBookmarkRestrictionModal = false },
             icon = R.drawable.ic_gradient_bookmark,
         )
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt`
around lines 129 - 138, The OneButtonModal in CollectionDetailScreen contains a
hardcoded "5" in the message string for the bookmark restriction modal, but
SavedContentUiState.MIN_REQUIRED_COUNT constant is already used elsewhere for
the same purpose. Replace the hardcoded "5" in the message parameter with a
reference to SavedContentUiState.MIN_REQUIRED_COUNT to ensure consistency across
the codebase and allow future changes to be made in a single location.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt`:
- Around line 96-101: The totalCount calculation in the state update does not
have a lower bound check and can become negative when the -1 operation is
applied during unbookmarking, especially if the local state is out of sync. Fix
this by applying a minimum value constraint (coerce to at least 0) to the
totalCount value in the line where totalCount is calculated using the
conditional expression with if (isBookmarked) 1 else -1, ensuring the value
never goes below zero.

---

Nitpick comments:
In
`@app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt`:
- Around line 129-138: The OneButtonModal in CollectionDetailScreen contains a
hardcoded "5" in the message string for the bookmark restriction modal, but
SavedContentUiState.MIN_REQUIRED_COUNT constant is already used elsewhere for
the same purpose. Replace the hardcoded "5" in the message parameter with a
reference to SavedContentUiState.MIN_REQUIRED_COUNT to ensure consistency across
the codebase and allow future changes to be made in a single location.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59ac4db7-575e-42eb-91d2-62a1a4df0356

📥 Commits

Reviewing files that changed from the base of the PR and between 7ad37b2 and 6abb457.

📒 Files selected for processing (13)
  • app/src/main/java/com/flint/core/designsystem/component/listView/SavedContentsSection.kt
  • app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt
  • app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailViewModel.kt
  • app/src/main/java/com/flint/presentation/collectiondetail/sideeffect/CollectionDetailSideEffect.kt
  • app/src/main/java/com/flint/presentation/main/MainNavHost.kt
  • app/src/main/java/com/flint/presentation/profile/ProfileScreen.kt
  • app/src/main/java/com/flint/presentation/profile/ProfileViewModel.kt
  • app/src/main/java/com/flint/presentation/profile/SavedContentScreen.kt
  • app/src/main/java/com/flint/presentation/profile/SavedContentSideEffect.kt
  • app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt
  • app/src/main/java/com/flint/presentation/profile/navigation/ProfileNavigation.kt
  • app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileScreen.kt
  • app/src/main/java/com/flint/presentation/setting/editprofile/navigation/EditProfileNavigation.kt

Comment on lines +96 to 101
totalCount = currentList.totalCount + if (isBookmarked) 1 else -1,
contents = currentList.contents
.map { if (it.id == contentId) it.copy(isBookmarked = isBookmarked) else it }
.toPersistentList()
)
state.copy(contents = UiState.Success(updated))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

totalCount 음수 하한 보정이 필요합니다.

Line 96은 -1 연산만 수행해서 로컬 상태가 어긋난 경우 음수 카운트가 노출될 수 있습니다. 하한을 0으로 고정해 주세요.

제안 패치
-                            totalCount = currentList.totalCount + if (isBookmarked) 1 else -1,
+                            totalCount = (currentList.totalCount + if (isBookmarked) 1 else -1).coerceAtLeast(0),

Based on learnings, toggle API 응답은 boolean 상태 중심으로 클라이언트에서 count를 계산하되 상태 동기화 안전성을 보장해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt`
around lines 96 - 101, The totalCount calculation in the state update does not
have a lower bound check and can become negative when the -1 operation is
applied during unbookmarking, especially if the local state is out of sync. Fix
this by applying a minimum value constraint (coerce to at least 0) to the
totalCount value in the line where totalCount is calculated using the
conditional expression with if (isBookmarked) 1 else -1, ensuring the value
never goes below zero.

Source: Learnings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant