[feat] #80 스플래시~이용약관 프로세스 구성#91
Conversation
…m-2-Android into feat/#80-login-onboarding
…m-2-Android into feat/#80-login-onboarding
약관과 관련해 API 추가로 연결해야 할 부분이 생겨 이후 PR에서 함께 반영하겠습니다! |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@feature/auth/impl/src/main/kotlin/com/neki/android/feature/auth/impl/login/LoginScreen.kt`:
- Line 25: The code stores a NekiToast with remember { NekiToast(context) }
which can capture a stale Context across configuration changes; update the
remember call to use context as a key (e.g., remember(context) {
NekiToast(context) }) so a new NekiToast is created when context changes,
targeting the nekiToast variable in LoginScreen.kt.
🧹 Nitpick comments (4)
core/data/src/main/java/com/neki/android/core/data/repository/impl/TokenRepositoryImpl.kt (2)
20-23: companion object의 키를private으로 제한하세요.
ACCESS_TOKEN과REFRESH_TOKEN은 이 리포지토리의 내부 구현 세부사항입니다. 현재val로 선언되어 companion object 외부에서 접근 가능합니다. 불필요한 노출을 방지하기 위해private으로 변경하는 것이 좋습니다.♻️ 수정 제안
companion object { - val ACCESS_TOKEN = stringPreferencesKey("access_token") - val REFRESH_TOKEN = stringPreferencesKey("refresh_token") + private val ACCESS_TOKEN = stringPreferencesKey("access_token") + private val REFRESH_TOKEN = stringPreferencesKey("refresh_token") }
36-43:hasTokens()에서 불필요한 복호화 수행.토큰 존재 여부만 확인하면 되는데 매번
CryptoManager.decrypt()를 호출하고 있습니다. 암호화된 값 자체가 null이 아니고 blank가 아닌지만 확인하면 충분합니다. 복호화는 비용이 있는 연산이므로, 단순 존재 확인에서는 생략할 수 있습니다.♻️ 수정 제안
override fun hasTokens(): Flow<Boolean> { return dataStore.data.map { preferences -> - val accessToken = preferences[ACCESS_TOKEN]?.let { CryptoManager.decrypt(it) } - val refreshToken = preferences[REFRESH_TOKEN]?.let { CryptoManager.decrypt(it) } - - !accessToken.isNullOrBlank() && !refreshToken.isNullOrBlank() + !preferences[ACCESS_TOKEN].isNullOrBlank() && !preferences[REFRESH_TOKEN].isNullOrBlank() } }feature/auth/impl/src/main/kotlin/com/neki/android/feature/auth/impl/login/LoginScreen.kt (2)
30-40: 로그인 실패 시 사용자에게 피드백 없음
onFailure에서Timber.d로 로그만 남기고 있어, 사용자는 로그인 실패 원인을 알 수 없습니다. Toast나 에러 UI를 통해 실패를 알리는 것이 좋습니다.🛠️ 예시
onFailure = { message -> Timber.d("로그인 실패 $message") + nekiToast.showToast(text = message ?: "로그인에 실패했습니다.") },
46-47:else -> {}공백 분기를 제거하고 모든LoginSideEffect케이스를 명시적으로 처리
LoginSideEffect는 sealed interface이므로else분기 없이when을 사용하면 컴파일 타임에 모든 케이스를 강제로 처리하게 됩니다. 현재 코드는NavigateToMain,NavigateBack,NavigateUrl케이스를 처리하지 않으면서 공백else분기로 무시하고 있습니다. 향후 새로운 side effect가 추가되더라도 조용히 무시될 수 있으므로, 모든 케이스를 명시적으로 처리하거나 불필요한 케이스에 대해 의도적인 처리를 추가해야 합니다.
|
|
||
| val context = LocalContext.current | ||
| val kakaoAuthHelper = remember { KakaoAuthHelper(context) } | ||
| val nekiToast = remember { NekiToast(context) } |
There was a problem hiding this comment.
remember에 context 키가 누락되어 stale context 참조 위험
remember { NekiToast(context) }는 context를 키로 사용하지 않으므로, Configuration 변경(예: 화면 회전) 시 이전 context를 캡처한 NekiToast 인스턴스가 재사용됩니다. 이는 메모리 릭 또는 잘못된 Toast 표시로 이어질 수 있습니다.
🛠️ 수정 제안
- val nekiToast = remember { NekiToast(context) }
+ val nekiToast = remember(context) { NekiToast(context) }📝 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 nekiToast = remember { NekiToast(context) } | |
| val nekiToast = remember(context) { NekiToast(context) } |
🤖 Prompt for AI Agents
In
`@feature/auth/impl/src/main/kotlin/com/neki/android/feature/auth/impl/login/LoginScreen.kt`
at line 25, The code stores a NekiToast with remember { NekiToast(context) }
which can capture a stale Context across configuration changes; update the
remember call to use context as a key (e.g., remember(context) {
NekiToast(context) }) so a new NekiToast is created when context changes,
targeting the nekiToast variable in LoginScreen.kt.
[feat] #80 스플래시~이용약관 프로세스 구성
🔗 관련 이슈
📙 작업 설명
📸 스크린샷 또는 시연 영상 (선택)
KakaoTalk_Video_2026-02-08-15-51-45.mp4
KakaoTalk_Video_2026-02-08-15-52-27.mp4
KakaoTalk_Video_2026-02-08-15-58-58.mp4
KakaoTalk_Video_2026-02-08-15-58-30.mp4
💬 추가 설명 or 리뷰 포인트 (선택)
AuthNavigationState,AuthNavigator,AuthScreen를 정의하고, AuthScreen 내 별도NavDisplay()를 이용했습니다.LoginViewModel을 공유하고, Splash는 스플래시 이후의 화면 전환과 이후 딥링크 처리를 위해 별도SplashViewModel을 사용합니다.HiltSharedViewModelStoreNavEntryDecorator만으로 ViewModel이clear()되지 않고, 남아있는 현상이 있습니다.ex. 로그인/약관 동의 후 메인화면에 진입했을 때 LoginViewModel이 살아있는 현상이 있습니다. 반대로 메인화면에서 로그아웃/탈퇴 후 스플래시 화면으로 이동했을 때 탑레벨의 뷰모델이 모두 살아있는 현상이 있구요.
-> 이부분은 해당 pr에서 수정하면 변경사항이 너무 많을 것 같아 별도 이슈로 등록하여 수정하겠습니다!
Q. 현재 메인화면에서의 화면 전환에 사용되는 Navigator/NavigatorImpl을 MainNavigator/MainNavigatorImpl로 네이밍을 변경할까요?
Summary by CodeRabbit
새로운 기능
디자인 개선
기타