Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
package com.cherrish.android.presentation.onboarding.information

import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.waitForUpOrCancellation
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.relocation.BringIntoViewRequester
import androidx.compose.foundation.relocation.bringIntoViewRequester
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.input.ImeAction
Expand All @@ -33,7 +49,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.cherrish.android.core.common.extension.addFocusCleaner
import com.cherrish.android.core.common.extension.collectLatestSideEffect
import com.cherrish.android.core.designsystem.component.button.CherrishButton
import com.cherrish.android.core.designsystem.component.textfield.CherrishTextField
Expand Down Expand Up @@ -69,6 +84,7 @@ fun OnboardingInformationRoute(
)
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun OnboardingInformationScreen(
paddingValues: PaddingValues,
Expand All @@ -84,82 +100,144 @@ private fun OnboardingInformationScreen(
) {
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current
val density = LocalDensity.current

val nameFocusRequester = remember { FocusRequester() }
val ageFocusRequester = remember { FocusRequester() }
var isNameFocused by remember { mutableStateOf(false) }
var isAgeFocused by remember { mutableStateOf(false) }

Scaffold(
bottomBar = {
CherrishButton(
text = "다음",
onClick = onNextClick,
enabled = enabled,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 30.dp)
.background(CherrishTheme.colors.gray0)
.navigationBarsPadding()
val coroutineScope = rememberCoroutineScope()

val bringIntoViewRequester = remember { BringIntoViewRequester() }

)
LaunchedEffect(isNameFocused, isAgeFocused) {
if (isNameFocused || isAgeFocused) {
delay(300)
bringIntoViewRequester.bringIntoView()
}
) { innerPadding ->
Column(
modifier = modifier
.fillMaxSize()
.background(color = CherrishTheme.colors.gray0)
.addFocusCleaner(focusManager)
.padding(paddingValues = paddingValues)
.imePadding()
}

val listState = rememberLazyListState()
val imeBottom = WindowInsets.ime.getBottom(density)
val imeBottomDp = with(density) { imeBottom.toDp() }
val targetBottomInset = if (imeBottomDp > 0.dp) 0.dp else paddingValues.calculateBottomPadding()
val bottomInset by animateDpAsState(targetValue = targetBottomInset, label = "bottomInset")

Column(
modifier = modifier
.fillMaxSize()
.background(color = CherrishTheme.colors.gray0)
) {
Comment on lines +127 to +131
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and read the target file
cat -n app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt

Repository: TEAM-Cherrish/Cherrish-Android

Length of output: 15266


루트 Column에 paddingValues 적용 필수

현재 코드는 루트 Column에 .padding(paddingValues)를 적용하지 않고 있습니다. 대신 paddingValues에서 하단 패딩만 추출하여 버튼에만 적용되고 있어, 상태바와 내비게이션 바의 패딩이 제대로 처리되지 않을 수 있습니다. 루트 Column 수정자에 .padding(paddingValues)를 먼저 적용하세요.

✅ 적용 예시
     Column(
         modifier = modifier
             .fillMaxSize()
             .background(color = CherrishTheme.colors.gray0)
+            .padding(paddingValues)
     ) {
📝 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
Column(
modifier = modifier
.fillMaxSize()
.background(color = CherrishTheme.colors.gray0)
) {
Column(
modifier = modifier
.fillMaxSize()
.background(color = CherrishTheme.colors.gray0)
.padding(paddingValues)
) {
🤖 Prompt for AI Agents
In
`@app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt`
around lines 127 - 131, The root Column in OnboardingInformationScreen.kt is
missing application of the system padding; apply paddingValues to the Column
modifier first (i.e., include .padding(paddingValues) on the Column's modifier
before .fillMaxSize()/.background()) so window insets (status/nav bars) are
respected rather than only applying bottom inset to the button; update the
Column modifier where Column(...) is declared to use .padding(paddingValues)
then chain the existing .fillMaxSize() and .background().

LazyColumn(
state = listState,
modifier = Modifier
.fillMaxWidth()
.weight(1f),
contentPadding = PaddingValues(bottom = 24.dp)
) {
Spacer(modifier = Modifier.weight(135f))
UserInfoHeader()
Spacer(modifier = Modifier.weight(70f))
item {
Spacer(modifier = Modifier.height(157.dp))
}

stickyHeader {
Column(
modifier = Modifier
.fillMaxWidth()
.background(CherrishTheme.colors.gray0)
) {
UserInfoHeader()
}
}

UserInfoTextField(
textFieldName = "이름",
value = username,
onValueChange = onNameChange,
placeholder = "김체리",
keyboardImeAction = ImeAction.Next,
onNextAction = { ageFocusRequester.requestFocus() },
keyboardType = KeyboardType.Text,
errorText = "이름은 최대 7자까지 입력 가능합니다.",
errorCase = nameErrorCase
)
item {
Spacer(modifier = Modifier.height(70.dp))
}

Spacer(modifier = Modifier.weight(30f))
item {
Column(
modifier = Modifier
.bringIntoViewRequester(bringIntoViewRequester)
.windowInsetsPadding(WindowInsets.ime.only(WindowInsetsSides.Bottom))
) {
UserInfoTextField(
textFieldName = "이름",
value = username,
onValueChange = onNameChange,
placeholder = "김체리",
keyboardImeAction = ImeAction.Next,
onNextAction = { ageFocusRequester.requestFocus() },
keyboardType = KeyboardType.Text,
errorText = "이름은 최대 7자까지 입력 가능합니다.",
errorCase = nameErrorCase,
textFieldModifier = Modifier
.focusRequester(nameFocusRequester)
.pointerInput(Unit) {
awaitEachGesture {
awaitFirstDown(pass = PointerEventPass.Initial)
nameFocusRequester.requestFocus()
waitForUpOrCancellation()
}
}
.onFocusChanged { state ->
isNameFocused = state.isFocused
}
)

UserInfoTextField(
textFieldName = "나이",
value = age,
onValueChange = onAgeChange,
placeholder = "20",
keyboardImeAction = ImeAction.Done,
onDoneAction = {
keyboardController?.hide()
kotlinx.coroutines.MainScope().launch {
delay(100)
focusManager.clearFocus()
}
},
keyboardType = KeyboardType.Number,
visualTransformation = if (isAgeFocused) {
VisualTransformation.None
} else {
AgeSuffixTransformation(" 세")
},
errorText = "입력 가능한 최대 나이 100세를 초과했습니다.",
errorCase = ageErrorCase,
modifier = Modifier
.focusRequester(ageFocusRequester)
.onFocusChanged { state ->
isAgeFocused = state.isFocused
}
)
Spacer(modifier = Modifier.height(30.dp))

Spacer(modifier = Modifier.weight(200f))
UserInfoTextField(
textFieldName = "나이",
value = age,
onValueChange = onAgeChange,
placeholder = "20",
keyboardImeAction = ImeAction.Done,
onDoneAction = {
keyboardController?.hide()
coroutineScope.launch {
delay(100)
focusManager.clearFocus()
}
},
keyboardType = KeyboardType.Number,
visualTransformation = if (isAgeFocused) {
VisualTransformation.None
} else {
AgeSuffixTransformation(
" 세"
)
},
errorText = "입력 가능한 최대 나이 100세를 초과했습니다.",
errorCase = ageErrorCase,
textFieldModifier = Modifier
.focusRequester(ageFocusRequester)
.pointerInput(Unit) {
awaitEachGesture {
awaitFirstDown(pass = PointerEventPass.Initial)
ageFocusRequester.requestFocus()
waitForUpOrCancellation()
}
}
.onFocusChanged { state ->
isAgeFocused = state.isFocused
}
)
}

Spacer(modifier = Modifier.padding(innerPadding.calculateBottomPadding()))
Spacer(modifier = Modifier.height(24.dp))
}
}

CherrishButton(
text = "다음",
onClick = onNextClick,
enabled = enabled,
modifier = Modifier
.fillMaxWidth()
.background(CherrishTheme.colors.gray0)
.padding(horizontal = 24.dp)
.padding(top = 30.dp, bottom = 30.dp + bottomInset)
)
}
}

Expand All @@ -168,7 +246,7 @@ private fun UserInfoHeader() {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 26.dp),
.padding(horizontal = 15.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
Expand All @@ -195,6 +273,7 @@ private fun UserInfoTextField(
keyboardType: KeyboardType,
errorText: String,
modifier: Modifier = Modifier,
textFieldModifier: Modifier = Modifier,
onNextAction: () -> Unit = {},
onDoneAction: () -> Unit = {},
visualTransformation: VisualTransformation = VisualTransformation.None,
Expand Down Expand Up @@ -227,7 +306,7 @@ private fun UserInfoTextField(
onDoneAction = onDoneAction,
keyboardType = keyboardType,
visualTransformation = visualTransformation,
modifier = Modifier.fillMaxWidth()
modifier = textFieldModifier.fillMaxWidth()
)

Spacer(modifier = Modifier.height(4.dp))
Expand Down