Skip to content

Conversation

@rbqks529
Copy link
Contributor

@rbqks529 rbqks529 commented Oct 14, 2025

🚀 이슈번호

✏️ 변경사항

  • IOS에서 키보드를 내리기 위한 함수를 expect, actual 로 구현해서 화면에 연결했습니다.

📷 스크린샷

2025-10-14.5.17.12.mov

✍️ 사용법

🎸 기타

Summary by CodeRabbit

  • 신규 기능
    • 클럽 코드 및 이메일 인증 화면에서 6자리 입력 완료 시 키보드를 자동으로 숨깁니다.
    • 입력 칸 포커스 관리 개선: 마지막 자리 입력 시 포커스가 해제되어 오입력과 불필요한 키보드 노출을 줄입니다.
    • iOS에서 키보드가 즉시 닫히도록 동작을 보장하며, 기타 플랫폼에서도 동작을 확장할 수 있는 기반을 마련했습니다.
    • 전반적으로 입력 흐름이 매끄러워지고 가시성이 향상됩니다.

@rbqks529 rbqks529 self-assigned this Oct 14, 2025
@rbqks529 rbqks529 added FEAT 기능 개발 OK Merge 완료된 PR labels Oct 14, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 14, 2025

Walkthrough

멀티플랫폼 공통 expect 함수 hideKeyboard()를 추가하고, Android/JVM/Wasm JS에선 no-op actual, iOS에선 UIApplication.keyWindow?.endEditing(true) 호출로 구현. ClubCodeInputScreen과 EmailVerificationScreen에서 마지막 숫자 입력 시 focus 해제와 키보드 숨김 로직을 추가.

Changes

Cohort / File(s) Summary
Common API (expect)
composeApp/src/commonMain/kotlin/org/whosin/client/core/util/KeyboardUtil.kt
공통 expect 함수 hideKeyboard() 추가.
Platform actual 구현
composeApp/src/androidMain/kotlin/.../KeyboardUtil.android.kt, composeApp/src/iosMain/kotlin/.../KeyboardUtil.ios.kt, composeApp/src/jvmMain/kotlin/.../KeyboardUtil.jvm.kt, composeApp/src/wasmJsMain/kotlin/.../KeyboardUtil.wasmJs.kt
플랫폼별 actual fun hideKeyboard() 추가: iOS는 endEditing(true)로 구현, Android/JVM/Wasm JS는 no-op.
Auth 입력 화면 포커스/키보드 제어
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/clubcode/ClubCodeInputScreen.kt, composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/login/EmailVerificationScreen.kt
마지막(6번째) 숫자 입력 시 focusManager.clearFocus()hideKeyboard() 호출 추가. 일부 입력 이동 로직에 포커스 처리 보강 및 import 정리.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Screen as Input Screen
  participant Focus as FocusManager
  participant KBD as Software Keyboard
  participant Platform as hideKeyboard() (actual)

  User->>Screen: Digit enter (index 0..4)
  Screen->>Focus: move to next field
  Screen->>KBD: ensure shown

  User->>Screen: Digit enter (index 5)
  Screen->>Focus: clearFocus()
  Screen->>KBD: hide (local)
  Screen->>Platform: hideKeyboard()
  Note over Platform,Screen: iOS: endEditing(true)<br/>Other: no-op
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

여섯 번째 숨, 키보드는 살며시 쉰다
포커스는 내려놓고, 화면은 미소 짓네
iOS는 조용히 문을 닫고
나머지는 고요히 고개 끄덕여 🙇
한 줄의 expect, 네 변주의 actual
입력의 끝에, 깔끔한 안녕 👋

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 제목이 iOS용 키보드 내림 함수 구현 및 화면 연결을 구체적으로 언급하여 PR의 핵심 목표인 iOS expect/actual 구현과 화면 연동을 명확히 요약합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link

@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

🧹 Nitpick comments (4)
composeApp/src/iosMain/kotlin/org/whosin/client/core/util/KeyboardUtil.ios.kt (1)

8-12: iOS 구현이 잘 되어 있습니다.

메인 스레드에서 UI 작업을 처리하도록 dispatch_async를 사용한 점이 좋습니다. keyWindow가 iOS 13+에서 deprecated 되었지만, 프로젝트의 최소 지원 버전이 낮다면 현재 구현으로 충분합니다.

만약 iOS 13+ 전용이라면 다음과 같이 현대적인 API로 개선할 수 있습니다:

actual fun hideKeyboard() {
    dispatch_async(dispatch_get_main_queue()) {
        UIApplication.sharedApplication.windows
            .firstOrNull { it.isKeyWindow() }
            ?.endEditing(true)
    }
}
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/login/EmailVerificationScreen.kt (1)

140-145: 키보드 숨김 로직이 작동하지만 중복이 있습니다.

마지막 숫자 입력 시 세 가지 방식으로 키보드를 숨기고 있습니다:

  • focusManager.clearFocus() - 포커스 해제
  • keyboardController?.hide() - Compose 키보드 컨트롤러
  • hideKeyboard() - 새로운 플랫폼별 구현

이 defensive한 접근은 안전하지만, 실제로는 focusManager.clearFocus()hideKeyboard() 두 개만으로도 충분할 수 있습니다.

다음과 같이 단순화할 수 있습니다:

 // 마지막 자리 입력 완료 시 키보드 숨기기
 else if (input.isNotEmpty() && index == 5) {
     focusManager.clearFocus()
-    keyboardController?.hide()
     hideKeyboard()
 }
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/clubcode/ClubCodeInputScreen.kt (2)

166-171: EmailVerificationScreen과 동일한 중복 패턴입니다.

여기서도 세 가지 방식으로 키보드를 숨기고 있습니다. EmailVerificationScreen과 마찬가지로 keyboardController?.hide() 호출은 제거 가능합니다.

 // 마지막 자리 입력 완료 시 키보드 숨기기
 else if (input.isNotEmpty() && index == 5) {
     focusManager.clearFocus()
-    keyboardController?.hide()
     hideKeyboard()
 }

238-243: SUCCESS 상태 체크 로직을 확인해주세요.

onClick 핸들러 내부에서 currentState == ClubCodeState.SUCCESS를 체크하고 있는데, 이 시점에는 아직 confirmClubCode()가 호출된 직후라 상태가 변경되지 않았을 수 있습니다. 이 키보드 숨김 로직은 실행되지 않을 가능성이 높습니다.

이미 Line 89-91의 LaunchedEffect(currentState)에서 SUCCESS 상태일 때 키보드를 숨기고 있으므로, 이 중복 로직은 제거하는 것이 좋습니다.

 onClick = {
     if (isComplete) {
         viewModel.confirmClubCode(clubCode = fullCode)
-        if (currentState == ClubCodeState.SUCCESS) {
-            keyboardController?.hide()
-        }
     }
 },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67dd51b and 24df6b6.

📒 Files selected for processing (7)
  • composeApp/src/androidMain/kotlin/org/whosin/client/core/util/KeyboardUtil.android.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/core/util/KeyboardUtil.kt (1 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/clubcode/ClubCodeInputScreen.kt (7 hunks)
  • composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/login/EmailVerificationScreen.kt (4 hunks)
  • composeApp/src/iosMain/kotlin/org/whosin/client/core/util/KeyboardUtil.ios.kt (1 hunks)
  • composeApp/src/jvmMain/kotlin/org/whosin/client/core/util/KeyboardUtil.jvm.kt (1 hunks)
  • composeApp/src/wasmJsMain/kotlin/org/whosin/client/core/util/KeyboardUtil.wasmJs.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/login/EmailVerificationScreen.kt (1)
composeApp/src/commonMain/kotlin/org/whosin/client/presentation/auth/login/component/NumberInputBox.kt (4)
  • { "\u200B" } (48-48)
  • innerTextField (105-107)
  • NumberInputBox (32-111)
  • BasicTextField (71-110)
🪛 detekt (1.23.8)
composeApp/src/wasmJsMain/kotlin/org/whosin/client/core/util/KeyboardUtil.wasmJs.kt

[warning] 3-4: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

composeApp/src/androidMain/kotlin/org/whosin/client/core/util/KeyboardUtil.android.kt

[warning] 3-4: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

⏰ 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). (2)
  • GitHub Check: android-build
  • GitHub Check: ios-build
🔇 Additional comments (4)
composeApp/src/androidMain/kotlin/org/whosin/client/core/util/KeyboardUtil.android.kt (1)

3-4: Android에서는 no-op 구현이 적절합니다.

Android는 LocalSoftwareKeyboardController를 통해 키보드를 제어하므로 이 empty 구현은 의도된 것입니다. detekt의 EmptyFunctionBlock 경고는 멀티플랫폼 패턴에서 흔히 나타나는 false positive이므로 무시해도 됩니다.

composeApp/src/jvmMain/kotlin/org/whosin/client/core/util/KeyboardUtil.jvm.kt (1)

3-4: JVM 타겟에 적합한 구현입니다.

Desktop 환경에서는 별도의 키보드 숨김 처리가 필요 없으므로 no-op 구현이 올바른 접근입니다.

composeApp/src/commonMain/kotlin/org/whosin/client/core/util/KeyboardUtil.kt (1)

3-3: 깔끔한 멀티플랫폼 API 설계입니다.

expect/actual 패턴을 적절하게 사용했으며, 함수 시그니처가 명확합니다.

composeApp/src/wasmJsMain/kotlin/org/whosin/client/core/util/KeyboardUtil.wasmJs.kt (1)

3-4: wasmJs 타겟에 적절한 no-op 구현입니다.

웹 환경에서는 키보드 제어가 브라우저에 의해 자동으로 처리되므로 empty 구현이 올바릅니다. detekt 경고는 멀티플랫폼 패턴의 특성상 나타나는 false positive입니다.

@Nico1eKim Nico1eKim merged commit 2085c21 into WhosInRoom:develop Oct 14, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FEAT 기능 개발 OK Merge 완료된 PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants