Skip to content

Commit d7b0c90

Browse files
committed
Feat: 제보 화면 키보드 ux 개선
- 제보 제목 입력 후 '완료'를 누르면 카테고리 선택 창이 나타나도록 수정 - 카테고리 선택 후 제보 내용 입력 필드에 자동으로 포커스가 가도록 수정 - 제보 내용 입력 후 '완료'를 누르면 키보드가 내려가도록 수정
1 parent 4859c24 commit d7b0c90

3 files changed

Lines changed: 39 additions & 2 deletions

File tree

presentation/src/main/java/com/threegap/bitnagil/presentation/report/ReportScreen.kt

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import androidx.compose.foundation.layout.windowInsetsPadding
2626
import androidx.compose.foundation.lazy.LazyRow
2727
import androidx.compose.foundation.lazy.items
2828
import androidx.compose.foundation.rememberScrollState
29+
import androidx.compose.foundation.text.KeyboardActions
30+
import androidx.compose.foundation.text.KeyboardOptions
2931
import androidx.compose.foundation.verticalScroll
3032
import androidx.compose.material3.ExperimentalMaterial3Api
3133
import androidx.compose.material3.Text
@@ -36,7 +38,11 @@ import androidx.compose.runtime.remember
3638
import androidx.compose.runtime.setValue
3739
import androidx.compose.ui.Alignment
3840
import androidx.compose.ui.Modifier
41+
import androidx.compose.ui.focus.FocusRequester
42+
import androidx.compose.ui.focus.focusRequester
3943
import androidx.compose.ui.platform.LocalContext
44+
import androidx.compose.ui.platform.LocalFocusManager
45+
import androidx.compose.ui.text.input.ImeAction
4046
import androidx.compose.ui.text.style.TextAlign
4147
import androidx.compose.ui.tooling.preview.Preview
4248
import androidx.compose.ui.unit.dp
@@ -62,6 +68,7 @@ import com.threegap.bitnagil.presentation.report.model.ReportSideEffect
6268
import com.threegap.bitnagil.presentation.report.model.ReportState
6369
import com.threegap.bitnagil.presentation.report.model.SubmitState
6470
import com.threegap.bitnagil.presentation.report.model.uiTitle
71+
import kotlinx.coroutines.delay
6572
import org.orbitmvi.orbit.compose.collectAsState
6673
import org.orbitmvi.orbit.compose.collectSideEffect
6774

@@ -73,10 +80,15 @@ fun ReportScreenContainer(
7380
) {
7481
val context = LocalContext.current
7582
val uiState by viewModel.collectAsState()
83+
val contentFocusRequester = remember { FocusRequester() }
7684

7785
viewModel.collectSideEffect { sideEffect ->
7886
when (sideEffect) {
7987
is ReportSideEffect.NavigateToBack -> navigateToBack()
88+
is ReportSideEffect.FocusOnContent -> {
89+
delay(100)
90+
contentFocusRequester.requestFocus()
91+
}
8092
}
8193
}
8294

@@ -165,6 +177,7 @@ fun ReportScreenContainer(
165177
SubmitState.IDLE -> {
166178
ReportScreen(
167179
uiState = uiState,
180+
contentFocusRequester = contentFocusRequester,
168181
onReportTitleChange = viewModel::updateReportTitle,
169182
onReportContentChange = viewModel::updateReportContent,
170183
onShowImageSourceBottomSheet = viewModel::showImageSourceBottomSheet,
@@ -190,6 +203,7 @@ fun ReportScreenContainer(
190203
@Composable
191204
private fun ReportScreen(
192205
uiState: ReportState,
206+
contentFocusRequester: FocusRequester,
193207
onReportTitleChange: (String) -> Unit,
194208
onReportContentChange: (String) -> Unit,
195209
onShowImageSourceBottomSheet: () -> Unit,
@@ -200,6 +214,7 @@ private fun ReportScreen(
200214
onBackClick: () -> Unit,
201215
) {
202216
val scrollState = rememberScrollState()
217+
val focusManager = LocalFocusManager.current
203218

204219
Column(
205220
modifier = Modifier
@@ -250,6 +265,12 @@ private fun ReportScreen(
250265
value = uiState.reportTitle,
251266
onValueChange = onReportTitleChange,
252267
singleLine = true,
268+
keyboardActions = KeyboardActions(
269+
onDone = {
270+
focusManager.clearFocus()
271+
onShowReportCategoryBottomSheet()
272+
},
273+
),
253274
placeholder = {
254275
Text(
255276
text = "제보 제목을 작성해주세요.",
@@ -263,15 +284,28 @@ private fun ReportScreen(
263284
ReportField(title = "카테고리") {
264285
ReportCategorySelector(
265286
title = uiState.selectedCategory?.uiTitle,
266-
onClick = onShowReportCategoryBottomSheet,
287+
onClick = {
288+
focusManager.clearFocus()
289+
onShowReportCategoryBottomSheet()
290+
},
267291
)
268292
}
269293

270294
ReportField(title = "상세 제보 내용") {
271295
BitnagilTextField(
272296
value = uiState.reportContent,
273297
onValueChange = onReportContentChange,
274-
modifier = Modifier.height(88.dp),
298+
modifier = Modifier
299+
.height(88.dp)
300+
.focusRequester(contentFocusRequester),
301+
keyboardOptions = KeyboardOptions(
302+
imeAction = ImeAction.Done,
303+
),
304+
keyboardActions = KeyboardActions(
305+
onDone = {
306+
focusManager.clearFocus()
307+
},
308+
),
275309
placeholder = {
276310
Text(
277311
text = "어떤 위험인지 간단히 설명해주세요.(100자 내외)",
@@ -318,6 +352,7 @@ private fun ReportScreen(
318352
private fun Preview() {
319353
ReportScreen(
320354
uiState = ReportState.Init,
355+
contentFocusRequester = remember { FocusRequester() },
321356
onReportTitleChange = {},
322357
onReportContentChange = {},
323358
onRemoveImage = {},

presentation/src/main/java/com/threegap/bitnagil/presentation/report/ReportViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ReportViewModel @Inject constructor(
6666
fun hideReportCategoryBottomSheet() {
6767
intent {
6868
reduce { state.copy(reportCategoryBottomSheetVisible = false) }
69+
postSideEffect(ReportSideEffect.FocusOnContent)
6970
}
7071
}
7172

presentation/src/main/java/com/threegap/bitnagil/presentation/report/model/ReportSideEffect.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ package com.threegap.bitnagil.presentation.report.model
22

33
sealed interface ReportSideEffect {
44
data object NavigateToBack : ReportSideEffect
5+
data object FocusOnContent : ReportSideEffect
56
}

0 commit comments

Comments
 (0)