Skip to content

feat: Splash 화면 UI 구성 및 플로우 구현 #115

Merged
easyhooon merged 15 commits intodevelopfrom
BOOK-232-feature/#114
Aug 7, 2025
Merged

feat: Splash 화면 UI 구성 및 플로우 구현 #115
easyhooon merged 15 commits intodevelopfrom
BOOK-232-feature/#114

Conversation

@easyhooon
Copy link
Copy Markdown
Contributor

@easyhooon easyhooon commented Aug 6, 2025

🔗 관련 이슈

📙 작업 설명

  • 제곧내

🧪 테스트 내역 (선택)

  • 주요 기능 정상 동작 확인
  • 브라우저/기기에서 동작 확인
  • 엣지 케이스 테스트 완료
  • 기존 기능 영향 없음

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

reed_splash.mp4

💬 추가 설명 or 리뷰 포인트 (선택)

  • Android 15 미만 기기에서 정상동작하는지 확인 부탁드림니다.
  • Android 버전에 관계없이 통일성있게 WindowInsets 관련 처리를 위해 기존 delegateNavigator 방식에서 모든 화면을 Scaffold로 구성하는 방식으로 변경하였습니다! systemUiController를 통해 systemBars 영역을 transparent color로 채웠고, icon 색상만 조정하는 식으로 변경했습니다.

Summary by CodeRabbit

  • 신규 기능

    • 앱에 새로운 스플래시 스크린이 추가되었습니다. 녹색 배경과 로고, 안내 문구가 표시됩니다.
    • 스플래시 화면이 1초간 표시된 후 자동으로 다음 화면으로 이동합니다.
    • 홈, 라이브러리, 로그인, 검색, 상세, 기록, 설정 등 주요 화면들이 일관된 스캐폴드 구조로 개선되어 UI 패딩과 내비게이션 경험이 향상되었습니다.
    • 홈 및 라이브러리 화면에서 탭 선택 시 네비게이션 루트가 상태를 유지하며 재설정됩니다.
  • 스타일

    • 시스템 바 색상이 투명하게 변경되고, 다크 아이콘 설정이 일관되게 적용됩니다.
    • 여러 화면에서 기존 시스템 UI 컨트롤러 사용이 제거되고, 커스텀 스캐폴드 컴포넌트로 대체되었습니다.
    • 로그인, 약관 동의, 검색, 라이브러리, 설정 등 화면들의 레이아웃과 패딩이 스캐폴드 기반으로 재구성되었습니다.
  • 문서화

    • 스플래시 화면에 사용되는 안내 문구가 추가되었습니다.
  • 기타

    • 스플래시 관련 리소스(색상, 벡터 이미지, 테마 등)가 추가되었습니다.
    • 메인 액티비티의 테마가 스플래시 테마로 변경되었습니다.
    • 일부 네트워크 API 경로가 사용자 관련 경로로 수정되었습니다.
    • 기존 바텀 내비게이션 관련 클래스 및 화면이 제거되고, 관련 컴포넌트가 리팩토링되었습니다.
    • 앱 내 여러 컴포넌트의 패키지 구조와 접근 제한자가 일부 조정되었습니다.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 6, 2025

Walkthrough

스플래시 화면 UI 구현을 위해 새로운 테마, 색상, 벡터 드로어블, 문자열 리소스가 추가되었고, SplashPresenter에 1초 지연 로직이 도입되었습니다. SplashUi는 완전한 UI로 구현되었으며, 메인 액티비티와 관련 시스템 UI 색상 처리 로직이 단순화 및 통일되었습니다.

Changes

Cohort / File(s) Change Summary
Splash 테마 및 리소스 추가
core/designsystem/build.gradle.kts, core/designsystem/src/main/res/drawable/ic_dummy_splash.xml, core/designsystem/src/main/res/values/colors.xml, core/designsystem/src/main/res/values/splash.xml, feature/main/src/main/AndroidManifest.xml, feature/main/src/main/res/values/strings.xml
스플래시 화면을 위한 의존성(libs.androidx.splash) 추가, 벡터 드로어블 및 색상(green_500) 리소스 추가, splash 테마 정의, 메인 액티비티 테마를 splash 테마로 변경, splash_title 문자열 리소스 추가
Splash 화면 UI 및 로직 구현
feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt, feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt
SplashUi를 완전한 UI로 구현, SplashPresenter에 1초 지연 로직 추가 및 네비게이션 로직이 지연 후 실행되도록 변경, 프리뷰 컴포저블 추가
시스템 UI 색상 처리 개선
feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt, feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt, feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt
시스템 바 색상 설정 로직을 단순화 및 통일, 다크 테마 관련 조건 제거, DisposableEffect 내에서 일관되게 처리
API 엔드포인트 경로 수정
core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt
사용자 관련 인증 필요 엔드포인트 경로 변경 및 주석 추가
탭 선택 이벤트 및 네비게이션 상태 관리 추가
feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt, feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt, feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt, feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt
홈 및 라이브러리 화면에서 탭 선택 이벤트 추가 및 해당 이벤트 처리 로직에 네비게이터 루트 재설정 기능 추가
BottomNavigation 관련 코드 삭제 및 리팩토링
feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/*, feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt
BottomNavigation 관련 클래스, UI, 상태, DelegateNavigator 삭제, BottomNavigationScreen 객체 제거
ReedScaffold 적용 및 UI 구조 개선
다수 UI 파일 (feature/home, feature/library, feature/login, feature/detail, feature/onboarding, feature/record, feature/search, feature/settings, feature/webview 등)
기존 ReedFullScreen 또는 직접 Column 사용에서 ReedScaffold로 UI 컨테이너 변경, topBar 슬롯 활용, innerPadding 적용, systemBarsPadding 제거, 레이아웃 및 패딩 일관성 개선
네비게이션 대상 변경
feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt, feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt, feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt
로그인 후 및 약관 동의 후 네비게이션 대상 변경: BottomNavigationScreenHomeScreen
기타 변경
다수 파일 (feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt, feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt, feature/screens/build.gradle.kts, feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt, feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainTab.kt, feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions/Navigator.kt, feature/screens/src/main/res/drawable/*)
import 경로 변경, 빌드 설정 확장, 벡터 드로어블 및 문자열 리소스 추가, 함수 가시성 변경 등

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MainActivity
    participant SplashPresenter
    participant SplashUi

    User->>MainActivity: 앱 실행
    MainActivity->>SplashUi: SplashUi 표시
    SplashUi->>SplashPresenter: present() 호출
    SplashPresenter->>SplashPresenter: 1초 지연 시작 (LaunchedEffect)
    Note right of SplashPresenter: 1초 동안 Splash 화면 유지
    SplashPresenter->>MainActivity: 1초 후 네비게이션 로직 실행
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
스플래시 화면 UI 구현 (#114)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
BottomNavigation 관련 코드 삭제 (feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/*) 삭제는 스플래시 화면 UI 구현과 직접 관련 없으며, 리팩토링 또는 구조 변경으로 보임
ReedScaffold 적용 및 UI 구조 개선 (다수 UI 파일) 스플래시 화면 UI 구현 요구사항과 별개로 전체 UI 구조 개선 및 일관성 작업임
API 엔드포인트 경로 수정 (core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt) 스플래시 화면과 직접 관련 없는 백엔드 API 경로 변경임

Possibly related PRs

Suggested reviewers

  • seoyoon513

Poem

초록빛 스플래시, 반짝이는 시작
한 초의 기다림, 마음 설레네
투명한 바, 깔끔한 UI
토끼가 전하는 새로운 길
🐇✨
Booket 여정, 이제 시작!

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80a1cec and 7a19efb.

📒 Files selected for processing (11)
  • core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt (1 hunks)
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt (4 hunks)
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt (3 hunks)
  • feature/home/build.gradle.kts (0 hunks)
  • feature/library/build.gradle.kts (0 hunks)
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt (5 hunks)
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt (3 hunks)
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt (3 hunks)
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt (3 hunks)
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt (2 hunks)
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt (3 hunks)
💤 Files with no reviewable changes (2)
  • feature/home/build.gradle.kts
  • feature/library/build.gradle.kts
✅ Files skipped from review due to trivial changes (1)
  • core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt
🚧 Files skipped from review as they are similar to previous changes (8)
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.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: ci-build
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BOOK-232-feature/#114

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 3

🧹 Nitpick comments (3)
feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt (1)

46-46: Android 15 상태 바 색상 이슈 추적이 필요합니다.

TODO 주석에서 언급한 Android 15의 상태 바 색상 적용 문제는 사용자 경험에 영향을 줄 수 있습니다. PR 목표에서 Android 15 미만 기기에서의 테스트를 요청했는데, 이 이슈에 대한 대응 방안이나 추적 계획이 필요합니다.

이 이슈를 별도 이슈로 생성하여 추적하거나 workaround 방법을 찾는 것을 도와드릴까요?

core/designsystem/src/main/res/values/splash.xml (1)

4-8: 색상 리소스 사용을 고려해보세요.

하드코딩된 색상값(#FF2F9647) 대신 새로 추가된 @color/green_500 리소스를 사용하면 일관된 색상 관리가 가능합니다.

다음과 같이 수정을 제안합니다:

-        <item name="windowSplashScreenBackground">#FF2F9647</item>
+        <item name="windowSplashScreenBackground">@color/green_500</item>
feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt (1)

38-43: 스플래시 지연 로직이 잘 구현되었습니다.

Circuit retained state와 LaunchedEffect를 활용한 3초 지연 구현이 적절합니다.

하드코딩된 지연 시간을 상수로 추출하면 더 좋습니다:

+private const val SPLASH_DELAY_MILLIS = 3000L
+
 class SplashPresenter @AssistedInject constructor(
     // ...
 ) : Presenter<SplashUiState> {
     
     @Composable
     override fun present(): SplashUiState {
         // ...
         LaunchedEffect(Unit) {
-            delay(3000L)
+            delay(SPLASH_DELAY_MILLIS)
             isSplashTimeCompleted = true
         }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b430c06 and 6b2de61.

⛔ Files ignored due to path filters (1)
  • feature/main/src/main/res/drawable/ic_reed_logo.png is excluded by !**/*.png
📒 Files selected for processing (11)
  • app/src/main/AndroidManifest.xml (1 hunks)
  • core/designsystem/build.gradle.kts (1 hunks)
  • core/designsystem/src/main/res/drawable/ic_dummy_splash.xml (1 hunks)
  • core/designsystem/src/main/res/values/colors.xml (1 hunks)
  • core/designsystem/src/main/res/values/splash.xml (1 hunks)
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt (1 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt (1 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt (3 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt (1 hunks)
  • feature/main/src/main/res/values/strings.xml (1 hunks)
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#35
File: feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/TermsAgreementScreen.kt:127-127
Timestamp: 2025-07-09T01:14:29.836Z
Learning: In the Reed-Android project's TermsAgreementScreen.kt, the OnTermDetailClick event is intentionally passed an empty string for the URL parameter because the actual URLs for terms detail pages haven't been decided yet. This is a temporary implementation that will be updated once the URLs are finalized.
📚 Learning: reed-android 프로젝트에서는 `booket.android.feature` convention plugin을 사용하여 feature 모듈들의 공통 의존성을 관리한다. 이 p...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#61
File: feature/webview/build.gradle.kts:17-21
Timestamp: 2025-07-20T12:34:23.786Z
Learning: Reed-Android 프로젝트에서는 `booket.android.feature` convention plugin을 사용하여 feature 모듈들의 공통 의존성을 관리한다. 이 plugin은 Circuit, Compose, 그리고 core 모듈들의 의존성을 자동으로 포함하므로, 각 feature 모듈의 build.gradle.kts에서는 특별한 의존성(예: libs.logger, libs.kakao.auth)만 별도로 선언하면 된다.

Applied to files:

  • core/designsystem/build.gradle.kts
📚 Learning: kotlin에서 같은 패키지 내의 파일들은 패키지 레벨에 정의된 const val 상수를 import 없이 직접 접근할 수 있습니다. onboardingpresenter.kt와 o...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#77
File: feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt:73-73
Timestamp: 2025-07-29T07:02:18.885Z
Learning: Kotlin에서 같은 패키지 내의 파일들은 패키지 레벨에 정의된 const val 상수를 import 없이 직접 접근할 수 있습니다. OnboardingPresenter.kt와 OnboardingUi.kt 모두 com.ninecraft.booket.feature.onboarding 패키지에 속해 있어서 ONBOARDING_STEPS_COUNT 상수를 공유할 수 있습니다.

Applied to files:

  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt
📚 Learning: in circuit architecture, presenters receive the screen object directly as a constructor parameter (e...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#88
File: feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailPresenter.kt:18-47
Timestamp: 2025-07-31T23:30:37.547Z
Learning: In Circuit architecture, presenters receive the Screen object directly as a constructor parameter (e.g., Assisted private val screen: RecordDetailScreen), and screen parameters are accessed through this screen object (e.g., screen.recordId). Screen parameters should not be added as separate constructor parameters.

Applied to files:

  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt
📚 Learning: in circuit architecture, screen parameters are not manually passed to presenter constructors. the @c...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#88
File: feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailPresenter.kt:18-47
Timestamp: 2025-07-31T23:30:37.547Z
Learning: In Circuit architecture, screen parameters are not manually passed to presenter constructors. The CircuitInject annotation automatically handles the injection of the entire Screen object, making screen parameters accessible without explicitly adding them to the constructor or factory methods.

Applied to files:

  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt
📚 Learning: in the reed-android project using circuit architecture, delegatingnavigator was restored because nav...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#52
File: feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/screens/DelegatingNavigator.kt:0-0
Timestamp: 2025-07-16T15:54:19.322Z
Learning: In the Reed-Android project using Circuit architecture, DelegatingNavigator was restored because NavigableCircuitContent can only inject a single navigator, but the dual-navigator architecture (childNavigator for bottom navigation screens, rootNavigator for full-screen screens) requires a delegating component to work within Circuit's constraint.

Applied to files:

  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt
📚 Learning: reed android 프로젝트에서는 svg에서 vector drawable로 변환시 색상 매핑 대신 모드별 별도 아이콘 파일을 사용하는 방식을 선호한다. figma에서 svg e...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#55
File: core/designsystem/src/main/res/drawable/ic_x_circle.xml:6-11
Timestamp: 2025-07-17T23:41:33.929Z
Learning: Reed Android 프로젝트에서는 SVG에서 vector drawable로 변환시 색상 매핑 대신 모드별 별도 아이콘 파일을 사용하는 방식을 선호한다. Figma에서 SVG export한 형태를 그대로 사용하며, 다크모드 대응이 필요할 경우 drawable-night 폴더에 별도 아이콘을 배치하는 방식을 사용한다.

Applied to files:

  • core/designsystem/src/main/res/drawable/ic_dummy_splash.xml
🧬 Code Graph Analysis (1)
feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt (1)
core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/theme/Theme.kt (1)
  • ReedTheme (14-21)
⏰ 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: ci-build
🔇 Additional comments (10)
core/designsystem/build.gradle.kts (1)

16-16: 스플래시 화면 의존성 추가가 적절합니다.

androidx.splash 라이브러리를 core designsystem 모듈에 추가한 것이 올바릅니다. Android 12+ 스플래시 화면 API를 지원하며, 디자인 시스템 모듈이 스플래시 관련 리소스와 테마를 제공하는 적절한 위치입니다.

core/designsystem/src/main/res/values/colors.xml (1)

10-10: 스플래시 화면용 녹색 컬러 리소스 추가가 적절합니다.

Material Design 색상 명명 규칙을 따르며, 알파 채널이 포함된 올바른 hex 값을 사용했습니다.

app/src/main/AndroidManifest.xml (1)

22-22: 스플래시 테마 정의 확인 완료

스플래시 테마(Theme.Booket.Splash)가 리소스 파일에서 올바르게 정의되어 있습니다:

  • parent: Theme.SplashScreen
  • windowSplashScreenBackground: #FF2F9647
  • windowSplashScreenAnimatedIcon: @drawable/ic_dummy_splash
  • postSplashScreenTheme: @style/Theme.Booket

따라서 AndroidManifest.xml의 테마 변경은 적절하며 승인합니다.

feature/main/src/main/res/values/strings.xml (1)

5-5: 스플래시 제목 문자열 리소스 추가가 적절합니다.

앱의 핵심 가치를 잘 표현하는 명확한 한국어 텍스트이며, 리소스 이름도 descriptive하고 명명 규칙을 따릅니다.

feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt (1)

37-40: 시스템 바 색상 설정 간소화가 잘 적용되었습니다.

흰색 배경에 다크 아이콘을 항상 사용하도록 설정하여 앱 전반에 걸친 일관된 UI를 제공합니다.

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt (1)

121-132: 시스템 바 색상 관리 로직이 잘 개선되었습니다.

DisposableEffect를 하나로 통합하여 코드 중복을 제거하고, 카메라 화면의 어두운 테마에 적합한 시스템 바 색상 설정과 정리 로직이 명확하게 구현되었습니다.

feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt (1)

45-46: 스플래시 타이밍 제어 로직이 올바르게 구현되었습니다.

isSplashTimeCompleted 조건을 통해 최소 스플래시 시간을 보장하면서 데이터 로딩 완료 후 네비게이션하는 로직이 잘 구현되었습니다.

feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt (3)

3-27: Import 구문이 깔끔하게 정리되어 있습니다.

모든 import가 실제로 사용되고 있으며, 코드 구조에 맞게 잘 정리되어 있습니다.


71-77: Preview 구현이 적절합니다.

@DevicePreview 어노테이션과 ReedTheme을 사용한 프리뷰 구현이 올바르게 되어 있습니다.


34-43: 시스템 바 색상 일치 확인 완료

SplashUi.kt에서 사용된 Green500(0xFF2F9647)과 테마의 bgPrimary(ReedTheme.colors.bgPrimary)가 모두 동일하게 0xFF2F9647로 정의되어 있어 색상 불일치가 없습니다. 변경이 필요 없습니다.

Comment thread core/designsystem/src/main/res/drawable/ic_dummy_splash.xml
Comment on lines +55 to +58
systemUiController.setSystemBarsColor(
color = White,
darkIcons = true,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

시스템 바 색상 설정에 일관성 문제가 있습니다.

setStatusBarColorHomeBg 색상을 사용하지만, setSystemBarsColorWhite 색상을 사용하여 일관성이 없습니다. 또한 onDispose에서는 상태 바 색상만 재설정하고 시스템 바 색상은 재설정하지 않습니다.

다음과 같이 수정하는 것을 권장합니다:

 DisposableEffect(systemUiController) {
     systemUiController.setStatusBarColor(
         color = HomeBg,
         darkIcons = true,
     )
-
-    systemUiController.setSystemBarsColor(
-        color = White,
-        darkIcons = true,
-    )
+    systemUiController.setSystemBarsColor(
+        color = HomeBg,
+        darkIcons = true,
+    )

     onDispose {
         systemUiController.setStatusBarColor(
             color = White,
             darkIcons = true,
         )
+        systemUiController.setSystemBarsColor(
+            color = White,
+            darkIcons = true,
+        )
     }
 }
🤖 Prompt for AI Agents
In feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt
around lines 55 to 58, the system bar color settings are inconsistent:
setStatusBarColor uses HomeBg color while setSystemBarsColor uses White, and
onDispose only resets the status bar color but not the system bars color. To fix
this, update setSystemBarsColor to use HomeBg color for consistency and ensure
that onDispose resets both the status bar and system bars colors to their
original states.

Comment on lines +45 to +69
Box(
modifier = modifier
.fillMaxSize()
.background(ReedTheme.colors.bgPrimary),
contentAlignment = Alignment.Center,
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
painter = painterResource(R.drawable.ic_reed_logo),
contentDescription = "Reed Logo",
modifier = Modifier.width(182.dp),
)
Spacer(modifier.height(ReedTheme.spacing.spacing5))
Text(
text = stringResource(R.string.splash_title),
color = ReedTheme.colors.contentInverse,
style = ReedTheme.typography.heading2SemiBold,
)
Spacer(modifier.height(ReedTheme.spacing.spacing8))
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

UI 레이아웃 구현이 잘 되어 있으나 개선 사항이 있습니다.

레이아웃 구조와 테마 사용이 적절하지만, 다음 개선사항을 고려해보세요:

  1. 접근성: 이미지의 contentDescription이 하드코딩되어 있습니다
  2. 일관성: modifier 매개변수가 Spacer에서 일관성 없게 사용되고 있습니다

다음 수정사항을 적용해보세요:

            Image(
                painter = painterResource(R.drawable.ic_reed_logo),
-               contentDescription = "Reed Logo",
+               contentDescription = stringResource(R.string.reed_logo_description),
                modifier = Modifier.width(182.dp),
            )
-           Spacer(modifier.height(ReedTheme.spacing.spacing5))
+           Spacer(Modifier.height(ReedTheme.spacing.spacing5))
            Text(
                text = stringResource(R.string.splash_title),
                color = ReedTheme.colors.contentInverse,
                style = ReedTheme.typography.heading2SemiBold,
            )
-           Spacer(modifier.height(ReedTheme.spacing.spacing8))
+           Spacer(Modifier.height(ReedTheme.spacing.spacing8))

그리고 strings.xml에 다음을 추가해주세요:

<string name="reed_logo_description">Reed 로고</string>
🤖 Prompt for AI Agents
In
feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt
between lines 45 and 69, update the Image composable's contentDescription to use
a string resource instead of a hardcoded string for accessibility; replace "Reed
Logo" with stringResource(R.string.reed_logo_description). Also, ensure
consistent usage of the modifier parameter by changing Spacer calls from
modifier.height(...) to Modifier.height(...). Finally, add the string
"reed_logo_description" with the value "Reed 로고" to strings.xml as instructed.

@easyhooon
Copy link
Copy Markdown
Contributor Author

easyhooon commented Aug 6, 2025

왜 windowInsets 관련 fix PR merge 했는데 conflict가 안나지?????
-> 반영 완료

@seoyoon513
Copy link
Copy Markdown
Contributor

@easyhooon Android 14에서 실행했을 떄 홈 화면에서 statusBar 색상 적용이 안되고 있습니다
스플래시 3초는 꽤 길긴 하네요

Reed_._._status_.mp4

@easyhooon
Copy link
Copy Markdown
Contributor Author

Android 14에서 실행했을 떄 홈 화면에서 statusBar 색상 적용이 안되고 있습니다

shit,,

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: 0

♻️ Duplicate comments (1)
feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt (1)

47-81: 스캐폴드와 바텀바 통합이 잘 구현되었습니다.

ReedScaffold를 사용하여 MainBottomBar를 통합하고, 탭 선택 이벤트 처리가 적절히 구현되었습니다. 이전의 시스템 UI 컨트롤러 관련 일관성 문제도 해결되었습니다.

🧹 Nitpick comments (1)
feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt (1)

135-142: 네비게이션 유틸리티 함수의 명명을 개선하세요.

popUntilOrGoTo 함수명이 함수의 동작을 명확히 표현하지 못합니다. 함수는 백스택에 화면이 존재하면 해당 화면으로 돌아가고, 없으면 새로 이동하는 로직입니다.

더 명확한 이름으로 변경을 고려해보세요:

-fun Navigator.popUntilOrGoTo(screen: Screen) {
+fun Navigator.navigateToScreenOrPopBack(screen: Screen) {

또는

-fun Navigator.popUntilOrGoTo(screen: Screen) {
+fun Navigator.goToOrPopUntil(screen: Screen) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b4e0500 and 80a1cec.

📒 Files selected for processing (39)
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt (4 hunks)
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt (3 hunks)
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt (1 hunks)
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt (1 hunks)
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt (2 hunks)
  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt (1 hunks)
  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt (2 hunks)
  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt (2 hunks)
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt (2 hunks)
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt (2 hunks)
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt (2 hunks)
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt (2 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt (2 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationPresenter.kt (0 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUi.kt (0 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUiState.kt (0 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/DelegateNavigator.kt (0 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt (3 hunks)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt (1 hunks)
  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt (2 hunks)
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt (4 hunks)
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt (1 hunks)
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt (3 hunks)
  • feature/screens/build.gradle.kts (2 hunks)
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt (0 hunks)
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt (2 hunks)
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainTab.kt (1 hunks)
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions/Navigator.kt (1 hunks)
  • feature/screens/src/main/res/drawable/ic_home.xml (1 hunks)
  • feature/screens/src/main/res/drawable/ic_library.xml (1 hunks)
  • feature/screens/src/main/res/drawable/ic_selected_home.xml (1 hunks)
  • feature/screens/src/main/res/drawable/ic_selected_library.xml (1 hunks)
  • feature/screens/src/main/res/values/strings.xml (1 hunks)
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt (1 hunks)
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt (3 hunks)
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt (3 hunks)
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt (2 hunks)
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt (2 hunks)
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt (3 hunks)
💤 Files with no reviewable changes (5)
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUi.kt
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUiState.kt
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationPresenter.kt
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/DelegateNavigator.kt
✅ Files skipped from review due to trivial changes (13)
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions/Navigator.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt
  • feature/screens/src/main/res/drawable/ic_selected_home.xml
  • feature/screens/src/main/res/drawable/ic_home.xml
  • feature/screens/src/main/res/drawable/ic_selected_library.xml
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainTab.kt
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt
  • feature/screens/src/main/res/values/strings.xml
  • feature/screens/src/main/res/drawable/ic_library.xml
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt
🚧 Files skipped from review as they are similar to previous changes (5)
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt
  • feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt
  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt
🧰 Additional context used
🧠 Learnings (16)
📚 Learning: in the reed-android project's delegatenavigator implementation, the pop(), peek(), and peekbackstack...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#52
File: feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/screens/DelegateNavigator.kt:0-0
Timestamp: 2025-07-16T16:11:27.044Z
Learning: In the Reed-Android project's DelegateNavigator implementation, the pop(), peek(), and peekBackStack() methods should always use childNavigator without branching logic, as they operate on the currently active navigation stack. Only goTo() and resetRoot() methods need to route between childNavigator and rootNavigator based on screen type using isMainTabScreen() function.

Applied to files:

  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt
📚 Learning: in the reed-android project's delegatenavigator implementation, the pop(), peek(), and peekbackstack...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#52
File: feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/screens/DelegateNavigator.kt:0-0
Timestamp: 2025-07-16T16:11:27.044Z
Learning: In the Reed-Android project's DelegateNavigator implementation, the pop(), peek(), and peekBackStack() methods should always use childNavigator without branching logic, as they operate on the currently active navigation stack. Only goTo() and resetRoot() methods need to route between childNavigator and rootNavigator based on screen type.

Applied to files:

  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
📚 Learning: in the reed-android project's termsagreementscreen.kt, the ontermdetailclick event is intentionally ...
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#35
File: feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/TermsAgreementScreen.kt:127-127
Timestamp: 2025-07-09T01:14:29.836Z
Learning: In the Reed-Android project's TermsAgreementScreen.kt, the OnTermDetailClick event is intentionally passed an empty string for the URL parameter because the actual URLs for terms detail pages haven't been decided yet. This is a temporary implementation that will be updated once the URLs are finalized.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
📚 Learning: in the reed-android project using circuit architecture, delegatingnavigator was restored because nav...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#52
File: feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/screens/DelegatingNavigator.kt:0-0
Timestamp: 2025-07-16T15:54:19.322Z
Learning: In the Reed-Android project using Circuit architecture, DelegatingNavigator was restored because NavigableCircuitContent can only inject a single navigator, but the dual-navigator architecture (childNavigator for bottom navigation screens, rootNavigator for full-screen screens) requires a delegating component to work within Circuit's constraint.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
📚 Learning: kotlin에서 같은 패키지 내의 파일들은 패키지 레벨에 정의된 const val 상수를 import 없이 직접 접근할 수 있습니다. onboardingpresenter.kt와 o...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#77
File: feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt:73-73
Timestamp: 2025-07-29T07:02:18.885Z
Learning: Kotlin에서 같은 패키지 내의 파일들은 패키지 레벨에 정의된 const val 상수를 import 없이 직접 접근할 수 있습니다. OnboardingPresenter.kt와 OnboardingUi.kt 모두 com.ninecraft.booket.feature.onboarding 패키지에 속해 있어서 ONBOARDING_STEPS_COUNT 상수를 공유할 수 있습니다.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
📚 Learning: reed-android 프로젝트에서는 `booket.android.feature` convention plugin을 사용하여 feature 모듈들의 공통 의존성을 관리한다. 이 p...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#61
File: feature/webview/build.gradle.kts:17-21
Timestamp: 2025-07-20T12:34:23.786Z
Learning: Reed-Android 프로젝트에서는 `booket.android.feature` convention plugin을 사용하여 feature 모듈들의 공통 의존성을 관리한다. 이 plugin은 Circuit, Compose, 그리고 core 모듈들의 의존성을 자동으로 포함하므로, 각 feature 모듈의 build.gradle.kts에서는 특별한 의존성(예: libs.logger, libs.kakao.auth)만 별도로 선언하면 된다.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/screens/build.gradle.kts
  • feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
  • feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
  • feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt
📚 Learning: reed android 프로젝트에서는 다크모드/라이트모드 대응 계획이 없고 기본 테마 값만 사용할 예정이다....
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#32
File: core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/theme/Theme.kt:15-21
Timestamp: 2025-07-08T03:21:24.693Z
Learning: Reed Android 프로젝트에서는 다크모드/라이트모드 대응 계획이 없고 기본 테마 값만 사용할 예정이다.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
📚 Learning: reed android 프로젝트에서 kakao 버튼 스타일은 디자이너가 pressed 상태 색상을 별도로 정의하지 않았기 때문에 pressed 상태에서도 동일한 kakao 색상을 ...
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#32
File: core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/component/button/ButtonColorStyle.kt:10-16
Timestamp: 2025-07-08T12:33:01.863Z
Learning: Reed Android 프로젝트에서 KAKAO 버튼 스타일은 디자이너가 pressed 상태 색상을 별도로 정의하지 않았기 때문에 pressed 상태에서도 동일한 Kakao 색상을 사용한다.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
📚 Learning: reed android 프로젝트에서 타이포그래피 사용 규칙: 톱 앱바(top app bar)에서는 `headline2semibold`를 사용하고, 바텀시트(bottom sheet)...
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#45
File: core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/component/appbar/ReedTopAppBar.kt:65-65
Timestamp: 2025-07-12T01:33:57.101Z
Learning: Reed Android 프로젝트에서 타이포그래피 사용 규칙: 톱 앱바(Top App Bar)에서는 `headline2SemiBold`를 사용하고, 바텀시트(Bottom Sheet)에서는 `heading2SemiBold`를 사용한다. 이는 의도적인 디자인 시스템 차별화이다.

Applied to files:

  • feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
📚 Learning: feature/library의 librarypresenter에서 현재 filterchipstate의 카운트 값들은 ui 확인용 더미 데이터이며, api가 준비되면 실제 데이터로 교...
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#63
File: feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt:28-53
Timestamp: 2025-07-22T05:19:10.071Z
Learning: feature/library의 LibraryPresenter에서 현재 FilterChipState의 카운트 값들은 UI 확인용 더미 데이터이며, API가 준비되면 실제 데이터로 교체될 예정입니다.

Applied to files:

  • feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt
📚 Learning: in circuit architecture, presenters receive the screen object directly as a constructor parameter (e...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#88
File: feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailPresenter.kt:18-47
Timestamp: 2025-07-31T23:30:37.547Z
Learning: In Circuit architecture, presenters receive the Screen object directly as a constructor parameter (e.g., Assisted private val screen: RecordDetailScreen), and screen parameters are accessed through this screen object (e.g., screen.recordId). Screen parameters should not be added as separate constructor parameters.

Applied to files:

  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
📚 Learning: jetpack compose에서 scale() 변환은 시각적 변환만 적용하며 레이아웃 좌표계는 변경하지 않는다. 따라서 scale(scalex = -1f, scaley = -1f)...
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#72
File: feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/component/CameraFrame.kt:21-82
Timestamp: 2025-07-28T18:08:47.298Z
Learning: Jetpack Compose에서 scale() 변환은 시각적 변환만 적용하며 레이아웃 좌표계는 변경하지 않는다. 따라서 scale(scaleX = -1f, scaleY = -1f)로 반전된 아이콘에서 padding()은 원래 레이아웃 기준으로 동작하므로, 시각적으로 올바른 위치를 위해서는 변환 전 좌표계 기준으로 padding을 설정해야 한다.

Applied to files:

  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt
  • feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt
  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt
📚 Learning: bookdetailscreen의 recordscollection 컴포넌트는 상위 column의 verticalscroll과 lazycolumn의 무한 스크롤을 동시에 지원해야 하는...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#88
File: feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/component/RecordsCollection.kt:25-59
Timestamp: 2025-07-31T23:22:02.816Z
Learning: BookDetailScreen의 RecordsCollection 컴포넌트는 상위 Column의 verticalScroll과 LazyColumn의 무한 스크롤을 동시에 지원해야 하는 중첩 스크롤 시나리오입니다. LazyColumn에 고정 높이를 설정하지 않으면 앱이 충돌하는 이슈가 있어서, 현재는 높이를 계산하여 설정하고 userScrollEnabled = false로 구현되어 있습니다. 향후 InfiniteLazyColumn과 nestedScrollConnection을 도입하여 전체 화면 스크롤 + LazyColumn 무한 스크롤을 지원할 예정입니다.

Applied to files:

  • feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt
📚 Learning: feature/settings oss 라이선스 화면의 현재 구현은 임시 구현이며, oss_licenses.json이 remote 데이터로 관리될 때 로딩 상태 및 에러 처리가 적용...
Learnt from: seoyoon513
PR: YAPP-Github/Reed-Android#45
File: feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesScreen.kt:55-59
Timestamp: 2025-07-12T03:51:35.793Z
Learning: feature/settings OSS 라이선스 화면의 현재 구현은 임시 구현이며, oss_licenses.json이 remote 데이터로 관리될 때 로딩 상태 및 에러 처리가 적용될 예정입니다.

Applied to files:

  • feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt
📚 Learning: reed-android 프로젝트에서 core:model 모듈은 순수 kotlin 모듈이므로 android 리소스(r.string 등)에 접근할 수 없다....
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#88
File: core/model/src/main/kotlin/com/ninecraft/booket/core/model/EmotionModel.kt:11-18
Timestamp: 2025-07-31T16:58:59.404Z
Learning: Reed-Android 프로젝트에서 core:model 모듈은 순수 Kotlin 모듈이므로 Android 리소스(R.string 등)에 접근할 수 없다.

Applied to files:

  • feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt
📚 Learning: reed-android 프로젝트에서는 api가 준비되지 않은 상황에서 ui를 먼저 구현하고, api 연동 시점에 하드코딩된 데이터를 실제 데이터로 교체하는 개발 방식을 사용한다. ...
Learnt from: easyhooon
PR: YAPP-Github/Reed-Android#88
File: feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/component/RecordItem.kt:29-37
Timestamp: 2025-07-31T23:17:40.054Z
Learning: Reed-Android 프로젝트에서는 API가 준비되지 않은 상황에서 UI를 먼저 구현하고, API 연동 시점에 하드코딩된 데이터를 실제 데이터로 교체하는 개발 방식을 사용한다. RecordItem 컴포넌트의 emotionTags 매개변수도 API 연동 시점에 `text = emotionTags.joinToString(separator = "·") { "#$it" }`로 적용될 예정이다.

Applied to files:

  • feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt
🧬 Code Graph Analysis (2)
feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt (1)
core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/ReedScaffold.kt (1)
  • ReedScaffold (13-35)
feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt (2)
core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/ReedScaffold.kt (1)
  • ReedScaffold (13-35)
core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/component/ReedTopAppBar.kt (1)
  • ReedBackTopAppBar (86-101)
🔇 Additional comments (32)
feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt (1)

5-5: 탭 선택 이벤트 추가가 적절합니다.

MainTab 타입을 사용한 OnTabSelected 이벤트 추가가 깔끔하게 구현되었습니다. 네비게이션 리팩토링의 일환으로 일관된 패턴을 따르고 있습니다.

Also applies to: 31-31

feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt (1)

6-6: 일관된 탭 선택 패턴 적용이 잘되었습니다.

홈 피처와 동일한 패턴으로 탭 선택 이벤트를 추가하여 일관성을 유지하고 있습니다.

Also applies to: 44-44

feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt (1)

135-141: 탭 선택 시 네비게이션 처리가 올바르게 구현되었습니다.

navigator.resetRoot를 사용하여 탭 화면으로 이동하면서 saveStaterestoreState를 true로 설정한 것이 적절합니다. 탭 전환 시 사용자의 상태를 보존할 수 있습니다.

feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt (1)

21-22: ReedScaffold로의 마이그레이션이 적절합니다.

UI 컨테이너를 ReedScaffold로 표준화하고 innerPadding을 적절히 적용한 것이 좋습니다. 시스템 UI 인셋 처리와 레이아웃 일관성이 개선됩니다.

Also applies to: 35-42

feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt (1)

82-88: 일관된 탭 네비게이션 처리가 잘 구현되었습니다.

LibraryPresenter와 동일한 패턴으로 탭 선택을 처리하여 일관성을 유지하고 있습니다. 상태 보존과 복원이 적절히 설정되어 있습니다.

feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt (2)

1-1: 패키지 이동이 적절하게 이루어졌습니다.

MainBottomBar를 공통 컴포넌트로 사용하기 위한 패키지 이동이 합리적입니다. 다른 feature 모듈들에서 공유할 수 있도록 적절히 위치가 변경되었습니다.


41-94: MainBottomBar 구현이 잘 되어 있습니다.

바텀바 UI 구성과 탭 선택 로직이 올바르게 구현되었습니다. 드롭 섀도우, 보더, 배경색 등 시각적 요소들도 적절히 적용되었습니다.

feature/screens/build.gradle.kts (2)

3-3: Compose 플러그인 추가가 적절합니다.

MainBottomBar와 같은 UI 컴포넌트를 포함하게 되면서 Compose 관련 플러그인 추가가 필요합니다.


12-20: 의존성 확장이 잘 구성되었습니다.

UI 컴포넌트와 네비게이션 기능을 위한 필요한 의존성들이 적절히 추가되었습니다. kotlinx.collections.immutable, circuit.foundation, compose.shadow 등이 MainBottomBar 구현에 필요한 라이브러리들입니다.

feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt (1)

27-27: ReedScaffold 도입이 적절합니다.

시스템 UI 컨트롤러 사용을 제거하고 ReedScaffold로 전환하여 UI 관리가 일관성 있게 개선되었습니다.

feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt (1)

62-88: ReedScaffold 전환이 일관성 있게 적용되었습니다.

다른 feature UI들과 동일한 패턴으로 ReedScaffold를 도입하여 레이아웃 관리와 패딩 처리가 통일되었습니다. systemBarsPadding 제거와 innerPadding 적용도 적절합니다.

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt (1)

48-98: ReedFullScreen에서 ReedScaffold로의 전환이 적절합니다.

TopAppBar를 스캐폴드의 topBar 슬롯으로 이동하고, 컨테이너 색상을 명시적으로 설정하여 UI 구조가 개선되었습니다. 기존 기능과 이벤트 처리 로직은 그대로 유지되어 안전한 리팩토링입니다.

feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt (2)

51-69: 스캐폴드 리팩터링이 잘 적용되었습니다.

ReedFullScreen에서 ReedScaffold로의 전환이 일관성 있게 구현되었습니다. 톱 앱바가 스캐폴드의 topBar 슬롯으로 이동되고, innerPadding이 콘텐츠에 올바르게 전달되고 있습니다.


73-82: innerPadding 적용이 올바릅니다.

콘텐츠 컴포저블에 innerPadding 파라미터가 추가되고 적절히 적용되어 스캐폴드의 인셋을 고려한 레이아웃이 구현되었습니다.

feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt (2)

57-74: 스캐폴드 패턴이 일관성 있게 적용되었습니다.

검색 UI에서도 ReedScaffold 패턴이 올바르게 적용되어 톱 앱바와 패딩 관리가 표준화되었습니다. ReedBackTopAppBar가 적절히 사용되고 있습니다.


86-87: 콘텐츠 modifier 단순화가 적절합니다.

SearchContent의 modifier에서 불필요한 배경색 설정이 제거되고 스캐폴드의 컨테이너 색상에 의존하도록 단순화된 것이 좋습니다.

feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt (2)

60-73: 스캐폴드 전환이 올바르게 구현되었습니다.

설정 UI에서 ReedScaffold 사용으로 레이아웃 관리가 표준화되었습니다. 톱 앱바가 스캐폴드의 topBar 슬롯에 올바르게 배치되었습니다.


181-185: 바텀시트 애니메이션 처리가 적절합니다.

취소 버튼에서 코루틴을 사용하여 바텀시트를 부드럽게 숨긴 후 이벤트를 발송하는 것이 UX 측면에서 올바른 구현입니다.

feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt (2)

28-44: 웹뷰 스캐폴드 구현이 적절합니다.

웹뷰 UI에서도 ReedScaffold 패턴이 일관성 있게 적용되어 톱 앱바와 패딩 관리가 표준화되었습니다. 타이틀이 state에서 동적으로 설정되는 것도 좋습니다.


53-82: innerPadding 적용이 올바릅니다.

웹뷰 콘텐츠를 감싸는 Box에 innerPadding이 적절히 적용되어 스캐폴드의 인셋을 고려한 레이아웃이 구현되었습니다. 웹뷰 설정은 그대로 유지되어 기능에 영향이 없습니다.

feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt (3)

69-84: 도서 상세 스캐폴드 구현이 적절합니다.

BookDetailUi에서 스캐폴드 패턴이 올바르게 적용되었습니다. 톱 앱바의 빈 타이틀은 이 화면의 디자인 의도에 맞는 구현으로 보입니다.


86-127: 바텀시트 배치가 올바릅니다.

바텀시트들이 스캐폴드 콘텐츠 외부에 배치된 것이 정확합니다. 이렇게 해야 전체 화면을 오버레이할 수 있습니다.


131-140: innerPadding 전달이 적절합니다.

BookDetailContentinnerPadding 파라미터가 추가되고 Column에 올바르게 적용되어 스캐폴드의 인셋을 고려한 스크롤 가능한 콘텐츠가 구현되었습니다.

feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt (9)

28-28: ReedScaffold 임포트 추가 승인

앱 전체의 일관된 스캐폴드 패턴 사용을 위한 적절한 임포트 추가입니다.


46-49: ReedScaffold 도입으로 레이아웃 일관성 개선

최상위 Column을 ReedScaffold로 교체하여 시스템 UI 패딩과 배경 색상 관리를 일관되게 처리하는 좋은 변경입니다.


50-54: innerPadding 적용으로 시스템 UI 충돌 방지

ReedScaffold의 innerPadding을 올바르게 적용하여 시스템 UI와의 충돌을 방지하는 좋은 구현입니다.


55-55: 디자인 시스템 스페이싱 사용 승인

ReedTheme.spacing을 사용하여 일관된 스페이싱을 적용한 좋은 구현입니다.


56-60: 레이아웃 구조 개선 승인

weight(1f)를 사용하여 버튼을 하단에 고정하고 내용 영역을 적절히 배치한 좋은 레이아웃 구조입니다.


61-65: 일관된 타이포그래피 적용 승인

ReedTheme의 타이포그래피를 사용하여 제목 스타일을 일관되게 적용한 좋은 구현입니다.


67-96: 전체 약관 동의 UI 개선 승인

테두리가 있는 클릭 가능한 Row로 구조를 변경하여 사용자 경험을 크게 개선했습니다. 체크박스와 텍스트의 수평 배치, 명확한 클릭 영역 표시, 적절한 패딩과 스페이싱 적용이 모두 우수합니다.


98-127: 개별 약관 항목 구현 승인

각 약관 항목이 TermItem 컴포넌트로 일관되게 구현되었으며, 적절한 스페이싱과 기능 설정이 적용되었습니다.


129-144: 시작 버튼 레이아웃 개선 승인

버튼을 메인 컬럼 내부로 이동시켜 레이아웃 구조를 개선했으며, 적절한 패딩과 상태 연동이 잘 구현되었습니다.

# Conflicts:
#	core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt
Scaffold topBar 슬롯에 topBar를 배치하는 경우 modifier를 통한 추가적인 padding을 적용해야하므로 topBar 까지 content 영역으로 이동

systemUiController 의존성 필요없는 모듈 의존성 제거
@easyhooon
Copy link
Copy Markdown
Contributor Author

easyhooon commented Aug 7, 2025

@seoyoon513 WindowInsets 관련 대응 진짜 완료!

참고로 ReedScaffold의 경우 텍스트필드에 대한 별도 처리를 포함하고 있는데,
보통 Compose Textfield의 경우 키보드의 완료를 눌러 키보드가 닫혀도, 텍스트필드에 대한 포커스가 남아있게 됩니다.
이때문에 키보드가 닫힌 상황에도 Textfield내에 커서가 깜빡거리게 되는 문제가 있는데,

완료 버튼을 누를 경우(그외에 다른 액션도 마찬가지) 이러한 포커스가 사라지도록 적용해두었슴니다.

Copy link
Copy Markdown
Contributor

@seoyoon513 seoyoon513 left a comment

Choose a reason for hiding this comment

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

Scaffold로 전부 마이그레이션하느라 고생 많으셨습니다~ statusBar 색상도 딜레이 없이 전환되네요
LGTM 👍👍

@easyhooon easyhooon merged commit 838870e into develop Aug 7, 2025
4 checks passed
@easyhooon easyhooon deleted the BOOK-232-feature/#114 branch August 7, 2025 06:22
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.

[BOOK-232/feat] Splash 화면 UI 구현

2 participants