Skip to content

[feat] #80 스플래시~이용약관 프로세스 구성#91

Merged
Ojongseok merged 54 commits into
developfrom
feat/#80-login-onboarding
Feb 8, 2026
Merged

[feat] #80 스플래시~이용약관 프로세스 구성#91
Ojongseok merged 54 commits into
developfrom
feat/#80-login-onboarding

Conversation

@Ojongseok
Copy link
Copy Markdown
Member

@Ojongseok Ojongseok commented Feb 8, 2026

🔗 관련 이슈

📙 작업 설명

  • 스플래시 / 온보딩 / 로그인 / 이용약관 흐름의 프로세스 및 UI 구성
  • 위 과정은 모두 feature:auth 모듈 내에서 진행됩니다.
  • Auth 관련 내비게이션 로직 작성
  • Title 28 폰트 시스템 추가

📸 스크린샷 또는 시연 영상 (선택)

기능 미리보기 기능 미리보기
온보딩
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 리뷰 포인트 (선택)

  • 스플래시~이용약관 : "Auth", 로그인&이용약관 : "Login~~"의 네이밍으로 사용됩니다.
  • 스플래시~약관까지의 화면 전환을 관리할 AuthNavigationState, AuthNavigator, AuthScreen를 정의하고, AuthScreen 내 별도 NavDisplay()를 이용했습니다.
  • 로그인과 약관은 LoginViewModel을 공유하고, Splash는 스플래시 이후의 화면 전환과 이후 딥링크 처리를 위해 별도 SplashViewModel을 사용합니다.
  • ViewModel을 공유하는 경우 RootNavKey 이동 시 기존에 작성된 HiltSharedViewModelStoreNavEntryDecorator 만으로 ViewModel이 clear() 되지 않고, 남아있는 현상이 있습니다.
    ex. 로그인/약관 동의 후 메인화면에 진입했을 때 LoginViewModel이 살아있는 현상이 있습니다. 반대로 메인화면에서 로그아웃/탈퇴 후 스플래시 화면으로 이동했을 때 탑레벨의 뷰모델이 모두 살아있는 현상이 있구요.
    -> 이부분은 해당 pr에서 수정하면 변경사항이 너무 많을 것 같아 별도 이슈로 등록하여 수정하겠습니다!

Q. 현재 메인화면에서의 화면 전환에 사용되는 Navigator/NavigatorImpl을 MainNavigator/MainNavigatorImpl로 네이밍을 변경할까요?

Summary by CodeRabbit

  • 새로운 기능

    • 인증 흐름 통합: 스플래시 → 3단계 온보딩 → 카카오 로그인 → 약관 화면 추가 및 연동
    • 온보딩 완료 상태 저장/해제 기능 추가
  • 디자인 개선

    • 다수 신규 벡터 아이콘(온보딩 일러스트, 로고, 카카오 등) 추가
    • 타이포그래피에 28pt 제목 스타일 추가
    • 그래디언트 배경 및 로그인 하단 카카오 버튼 UI 도입
  • 기타

    • 탈퇴 시 온보딩 상태 초기화로 재가입 유도 및 인증 흐름 안정화

@Ojongseok
Copy link
Copy Markdown
Member Author

리코멘트 남겼습니다! Image 는 이후 PR에서 답변온 뒤에 반영하실 예정인가요??

약관과 관련해 API 추가로 연결해야 할 부분이 생겨 이후 PR에서 함께 반영하겠습니다!

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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_TOKENREFRESH_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) }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

remembercontext 키가 누락되어 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.

Suggested change
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.

@Ojongseok Ojongseok merged commit b5586ab into develop Feb 8, 2026
3 checks passed
@Ojongseok Ojongseok deleted the feat/#80-login-onboarding branch February 9, 2026 22:30
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
Ojongseok added a commit that referenced this pull request May 25, 2026
[feat] #80 스플래시~이용약관 프로세스 구성
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.

[feat] 로그인, 온보딩 UI 구성

2 participants