Skip to content

Conversation

@juhwankim-dev
Copy link
Member

@juhwankim-dev juhwankim-dev commented Dec 28, 2025

개요

  • 진행률만 확인하고자 하는 사용자들이 있다.
  • 기존 방식은 힌트 코드를 입력하면 무조건 정답 사용 횟수가 카운트 된다.
  • 힌트 코드를 입력하면 진행률을 보여주고 힌트는 블러 처리하여 보이지 않도록 한다. 블러 처리한 부분에 자물쇠와 함께 안내 문구를 적어놓고, 사용자가 이를 클릭하면 힌트 사용 횟수가 증가하며 힌트가 노출되도록 한다.

변경사항

  • 힌트 화면 진입시 힌트 섹션 블러처리, 이미지는 미노출 (블러처리를 해도 대충 보일 수 있으니...)
  • 힌트 섹션 클릭시 힌트 사용 횟수 증가
  • 타이머 화면에서 힌트 사용 횟수 증가하시키는 로직은 제거
  • 힌트 사용 횟수 초과 체크 로직을 힌트 보기 버튼 클릭 했을때로 이동한다.

왜?
힌트 화면에서 버튼을 클릭하면 카운팅 하도록 변경할 예정임
그래서 타이머 화면에서 addOpenedHintId 호출하는 로직을 제거했고
gameSharedViewModel의 openedHintIds flow를 combine하여 화면을 그리도록 수정하였음
왜?
본 적 있는 힌트만 업데이트하면 되는데
기존에는 gameState를 전부 업데이트하고 있었음

어떻게?
updateUsedHints를 만들었음
그리고 gameSharedViewModel이 앞으로 본 적 있는 힌트를 관리할거라 여기서 업데이트 하도록 수정함
왜?
힌트 차감없이 진행률만 보고 싶어하는 손님들을 위한 로직 개선.
왜?
상태 관리를 하는 Flow를 하나로 두어 관리를 용이하게 한다.
왜?
정답을 본적이 있는지 여부는 gameSharedViewModel에서 따로 관리하기로 했음.
힌트, 타이머 화면에서 들고있을 필요가 없기 때문에 Hint 데이터 클래스에서 제거한다.
왜?
기존에는 Fragment가 collect해서 세팅해주었으나
assistedInject 받았으므로 바로 값을 꺼내 사용하도록 해준다.
@juhwankim-dev juhwankim-dev self-assigned this Dec 28, 2025
@github-actions
Copy link

🤖 AI Code Review (Gemini)

안녕하세요! NR-130 힌트 사용 기능 리뉴얼 Pull Request에 대한 코드 리뷰를 시작하겠습니다.

전반적으로 이번 PR은 힌트 사용 기능의 UX를 개선하고, 관련 상태 관리 로직을 GameSharedViewModel로 중앙화하여 ViewModel 간의 의존성을 명확히 한 훌륭한 리팩토링입니다. 특히 AssistedInject의 도입과 Compose UI의 유연한 활용이 돋보입니다.


긍정적인 측면

  1. 클린 아키텍처 준수: GameStateDao, GameStateRepositoryImpl, GameStateRepositoryupdateUsedHints를 추가하여 데이터 지속성 계층을 확장하면서도 도메인/데이터 계층 분리를 잘 유지했습니다.
  2. 효과적인 상태 관리: GameSharedViewModelGameSharedState의 도입은 열린 힌트/정답 상태와 같은 복잡한 게임 상태를 여러 Fragment 간에 공유하기 위한 견고한 솔루션입니다. HintViewModelTimerViewModel에서 combine 연산자를 사용하여 이 공유 ViewModel의 상태를 자신들의 UI 상태와 결합하는 방식은 매우 잘 구현되었습니다.
  3. AssistedInject 통합: assistedViewModel 확장 함수와 AssistedInject 설정은 런타임 의존성(GameSharedViewModel)이 필요한 ViewModel에 대해 올바르게 구현되었습니다. 이는 Hilt와 함께 복잡한 의존성을 관리하는 좋은 예시입니다.
  4. Compose UI 구현: HintScreen의 리팩토링은 Modifier.blur, Box 오버레이, throttleClick 등을 효과적으로 사용하여 새로운 사용자 경험을 성공적으로 구현했습니다. UI/UX 요구사항을 Compose로 깔끔하게 처리했습니다.
  5. 점진적인 Orbit MVI 마이그레이션: uiStatecombinestateIn을 통해 파생시키면서도 Orbit의 container를 사이드 이펙트 처리에 계속 사용하는 방식은 프로젝트의 Orbit 단계적 폐지 전략과 일치하며, 점진적인 전환을 잘 보여줍니다.
  6. 명확해진 책임: TimerViewModel은 힌트 코드 유효성 검사에, HintViewModel은 힌트 열기 로직 및 제한 검사에, GameSharedViewModel은 공유 게임 상태의 중앙화 및 지속성에 각각 책임을 가지도록 명확하게 분리되었습니다.

💡 개선 제안 (Suggestion)

  • presentation/src/main/java/com/nextroom/nextroom/presentation/extension/Fragment.kt
    • Line 113: crossinline 키워드는 람다 내부에서 비지역 반환(non-local return)을 허용할 때 사용됩니다. 현재 factory 람다 내부에서는 return 문이 없으므로 crossinline이 필수적이지는 않습니다. 물론 사용해도 문제는 없지만, 불필요한 경우 제거하여 코드를 더 간결하게 만들 수 있습니다. (매우 사소한 제안입니다.)
      // 변경 전
      inline fun <reified VM : ViewModel> Fragment.assistedViewModel(
          crossinline factory: () -> VM
      ): Lazy<VM> { ... }
      
      // 변경 후 (동일하게 동작)
      inline fun <reified VM : ViewModel> Fragment.assistedViewModel(
          factory: () -> VM
      ): Lazy<VM> { ... }

🔴 잠재적 버그 및 이슈 (Critical / Warning)

이번 PR에서 검토한 코드 변경사항에서는 Critical 또는 Warning 수준의 잠재적 버그나 이슈는 발견되지 않았습니다.


파일별 상세 리뷰

  • data/src/main/java/com/nextroom/nextroom/data/db/GameStateDao.kt
    • updateUsedHints(usedHints: Set<Int>) 추가: Set<Int> 타입은 힌트 ID의 고유성을 보장하고 효율적인 조회를 가능하게 하므로 적절합니다. UPDATE 쿼리도 올바르게 작성되었습니다.
  • data/src/main/java/com/nextroom/nextroom/data/repository/GameStateRepositoryImpl.kt
    • updateUsedHints 구현: gameStateDao.updateUsedHints로 직접 위임하여 올바르게 구현되었습니다.
  • domain/src/main/java/com/nextroom/nextroom/domain/repository/GameStateRepository.kt
    • updateUsedHints 추가: 도메인 계층에서 계약을 정의하여 클린 아키텍처 원칙을 준수합니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/extension/Fragment.kt
    • assistedViewModel 확장 함수 추가: AssistedInject를 Hilt와 Fragment.viewModels에 깔끔하게 통합하는 좋은 방법입니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/model/Hint.kt
    • answerOpened: Boolean 제거: 이 상태가 GameSharedState에서 외부적으로 관리되므로, Hint 데이터 모델의 순수성을 높이는 좋은 변경입니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/ui/hint/HintEvent.kt
    • OpenAnswer 제거, HintLimitExceed 추가: 새로운 상호작용 흐름에 맞춰 이벤트가 정확하게 반영되었습니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/ui/hint/HintFragment.kt
    • assistedViewModel 사용, gameSharedViewModel의 직접 collect 제거, HintScreen 콜백 업데이트: HintViewModel이 내부적으로 GameSharedViewModel의 상태를 combine하므로, Fragment의 initSubscribe가 간결해지고 새로운 상태 관리 방식에 잘 통합되었습니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/ui/hint/HintState.kt
    • isHintOpened, isAnswerOpened, totalHintCount 추가: UI가 흐림/선명 상태 및 힌트 제한을 올바르게 표시하는 데 필수적인 상태 필드입니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/ui/hint/HintViewModel.kt
    • AssistedInjectGameSharedViewModel과의 combine 사용: HintViewModelGameSharedViewModel의 상태를 결합하여 HintState를 파생시키는 방식은 매우 효과적입니다. tryOpenHint 로직도 힌트 제한 검사 및 GameSharedViewModel 업데이트를 포함하여 잘 구현되었습니다. Orbit MVI의 점진적 폐지 전략에 부합합니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/ui/hint/compose/HintScreen.kt
    • 주요 UI 변경: Modifier.blur, Box 오버레이, throttleClick을 사용하여 새로운 UI/UX 요구사항을 훌륭하게 구현했습니다. heightIn을 사용하여 흐림 처리된 영역의 최소 높이를 보장하는 것도 좋은 아이디어입니다.
  • presentation/src/main/java/com/nextroom/nextroom/presentation/ui/main/GameSharedViewModel.kt
    • GameSharedState 도입 및 공유 게임 상태 중앙화: 여러 Fragment 간에 복잡한 게임 상태를 공유하기 위한 핵심적이고 잘 설계된 구성 요소입니다. addOpenedHintId에서 gameStateRepository.updateUsedHints를 호출하여 상태를 즉시 저장하는 것도 올바른 처리입니다.
  • **`presentation/src/

This review was automatically generated using Gemini AI. Please use your judgment when addressing the feedback.

@juhwankim-dev
Copy link
Member Author

juhwankim-dev commented Dec 28, 2025

AI의 개선 제안 내용에서 언급된 crossinline을 빼면 컴파일 에러 발생하여 리뷰 반영하지 않겠습니다.
그 외 다른 개선점은 없으므로 머지합니다.

@juhwankim-dev juhwankim-dev merged commit 24c4215 into develop Dec 28, 2025
1 check passed
@juhwankim-dev juhwankim-dev deleted the feature/NR-130 branch December 28, 2025 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants