Skip to content

Commit 6ec7ad0

Browse files
committed
[BOOK-165] feat: Step 단위로 기록 등록 UI 구성
1 parent 57eea61 commit 6ec7ad0

File tree

9 files changed

+383
-133
lines changed

9 files changed

+383
-133
lines changed

core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/RecordStep.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.ninecraft.booket.core.designsystem
22

33
enum class RecordStep {
4-
REGISTER,
5-
APPRECIATION,
4+
QUOTE,
65
EMOTION,
6+
IMPRESSION,
77
;
88

99
val value: Int get() = ordinal

core/designsystem/src/main/kotlin/com/ninecraft/booket/core/designsystem/component/RecordProgressBar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fun RecordProgressBar(
3030
.height(6.dp)
3131
.clip(RoundedCornerShape(ReedTheme.radius.full))
3232
.background(
33-
color = if (currentStep.value == index) {
33+
color = if (index <= currentStep.ordinal) {
3434
ReedTheme.colors.bgPrimary
3535
} else {
3636
ReedTheme.colors.bgDisabled

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable
66
import androidx.compose.runtime.getValue
77
import androidx.compose.runtime.mutableStateOf
88
import androidx.compose.runtime.setValue
9+
import com.ninecraft.booket.core.designsystem.RecordStep
910
import com.ninecraft.booket.feature.screens.RecordScreen
1011
import com.slack.circuit.codegen.annotations.CircuitInject
1112
import com.slack.circuit.retained.rememberRetained
@@ -18,18 +19,32 @@ import dagger.hilt.android.components.ActivityRetainedComponent
1819

1920
class RecordRegisterPresenter @AssistedInject constructor(
2021
@Assisted private val navigator: Navigator,
21-
) : Presenter<RecordUiState> {
22+
) : Presenter<RecordRegisterUiState> {
2223

2324
@Composable
24-
override fun present(): RecordUiState {
25+
override fun present(): RecordRegisterUiState {
26+
var currentStep by rememberRetained { mutableStateOf(RecordStep.QUOTE) }
2527
val recordPageState = rememberTextFieldState()
2628
val recordSentenceState = rememberTextFieldState()
29+
val impressionState = rememberTextFieldState()
2730
var isExitDialogVisible by rememberRetained { mutableStateOf(false) }
2831

2932
fun handleEvent(event: RecordRegisterUiEvent) {
3033
when (event) {
3134
is RecordRegisterUiEvent.OnBackButtonClick -> {
32-
isExitDialogVisible = true
35+
when (currentStep) {
36+
RecordStep.QUOTE -> {
37+
isExitDialogVisible = true
38+
}
39+
40+
RecordStep.EMOTION -> {
41+
currentStep = RecordStep.QUOTE
42+
}
43+
44+
RecordStep.IMPRESSION -> {
45+
currentStep = RecordStep.EMOTION
46+
}
47+
}
3348
}
3449

3550
is RecordRegisterUiEvent.OnClearClick -> {
@@ -45,13 +60,29 @@ class RecordRegisterPresenter @AssistedInject constructor(
4560
}
4661

4762
is RecordRegisterUiEvent.OnSentenceScanButtonClick -> {}
48-
is RecordRegisterUiEvent.OnNextButtonClick -> {}
63+
is RecordRegisterUiEvent.OnNextButtonClick -> {
64+
when (currentStep) {
65+
RecordStep.QUOTE -> {
66+
currentStep = RecordStep.EMOTION
67+
}
68+
69+
RecordStep.EMOTION -> {
70+
currentStep = RecordStep.IMPRESSION
71+
}
72+
73+
RecordStep.IMPRESSION -> {
74+
// TODO: (기록 완료 API 성공 시) 기록 상세 화면 이동
75+
}
76+
}
77+
}
4978
}
5079
}
5180

52-
return RecordUiState(
81+
return RecordRegisterUiState(
82+
currentStep = currentStep,
5383
recordPageState = recordPageState,
5484
recordSentenceState = recordSentenceState,
85+
impressionState = impressionState,
5586
isExitDialogVisible = isExitDialogVisible,
5687
eventSink = ::handleEvent,
5788
)

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

Lines changed: 36 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,36 @@
11
package com.ninecraft.booket.feature.record.register
22

33
import androidx.activity.compose.BackHandler
4-
import androidx.compose.foundation.background
5-
import androidx.compose.foundation.layout.Column
64
import androidx.compose.foundation.layout.Spacer
75
import androidx.compose.foundation.layout.fillMaxSize
86
import androidx.compose.foundation.layout.fillMaxWidth
97
import androidx.compose.foundation.layout.height
108
import androidx.compose.foundation.layout.padding
11-
import androidx.compose.foundation.text.KeyboardOptions
12-
import androidx.compose.foundation.text.input.TextFieldLineLimits
13-
import androidx.compose.material3.Icon
14-
import androidx.compose.material3.Text
159
import androidx.compose.runtime.Composable
16-
import androidx.compose.ui.Alignment
1710
import androidx.compose.ui.Modifier
18-
import androidx.compose.ui.focus.FocusDirection
19-
import androidx.compose.ui.graphics.vector.ImageVector
20-
import androidx.compose.ui.platform.LocalFocusManager
2111
import androidx.compose.ui.res.stringResource
22-
import androidx.compose.ui.res.vectorResource
23-
import androidx.compose.ui.text.input.ImeAction
24-
import androidx.compose.ui.text.input.KeyboardType
25-
import androidx.compose.ui.unit.dp
2612
import com.ninecraft.booket.core.designsystem.DevicePreview
2713
import com.ninecraft.booket.core.designsystem.RecordStep
2814
import com.ninecraft.booket.core.designsystem.component.RecordProgressBar
2915
import com.ninecraft.booket.core.designsystem.component.button.ReedButton
3016
import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle
3117
import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle
32-
import com.ninecraft.booket.core.designsystem.component.button.smallRoundedButtonStyle
33-
import com.ninecraft.booket.core.designsystem.component.textfield.ReedRecordTextField
3418
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
35-
import com.ninecraft.booket.core.designsystem.theme.White
3619
import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar
3720
import com.ninecraft.booket.core.ui.component.ReedDialog
3821
import com.ninecraft.booket.core.ui.component.ReedFullScreen
3922
import com.ninecraft.booket.feature.record.R
23+
import com.ninecraft.booket.feature.record.step.EmotionStep
24+
import com.ninecraft.booket.feature.record.step.ImpressionStep
25+
import com.ninecraft.booket.feature.record.step.QuoteStep
4026
import com.ninecraft.booket.feature.screens.RecordScreen
4127
import com.slack.circuit.codegen.annotations.CircuitInject
4228
import dagger.hilt.android.components.ActivityRetainedComponent
43-
import com.ninecraft.booket.core.designsystem.R as designR
4429

4530
@CircuitInject(RecordScreen::class, ActivityRetainedComponent::class)
4631
@Composable
4732
internal fun RecordRegister(
48-
state: RecordUiState,
33+
state: RecordRegisterUiState,
4934
modifier: Modifier = Modifier,
5035
) {
5136
BackHandler {
@@ -60,7 +45,37 @@ internal fun RecordRegister(
6045
state.eventSink(RecordRegisterUiEvent.OnBackButtonClick)
6146
},
6247
)
63-
RecordRegisterContent(state = state)
48+
RecordProgressBar(
49+
currentStep = state.currentStep,
50+
modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5),
51+
)
52+
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing10))
53+
when (state.currentStep) {
54+
RecordStep.QUOTE -> {
55+
QuoteStep(state = state)
56+
}
57+
58+
RecordStep.EMOTION -> {
59+
EmotionStep(state = state)
60+
}
61+
62+
RecordStep.IMPRESSION -> {
63+
ImpressionStep(state = state)
64+
}
65+
}
66+
Spacer(modifier = Modifier.weight(1f))
67+
ReedButton(
68+
onClick = {
69+
state.eventSink(RecordRegisterUiEvent.OnNextButtonClick)
70+
},
71+
colorStyle = ReedButtonColorStyle.PRIMARY,
72+
sizeStyle = largeButtonStyle,
73+
modifier = Modifier
74+
.fillMaxWidth()
75+
.padding(horizontal = ReedTheme.spacing.spacing5),
76+
text = stringResource(R.string.record_next_button),
77+
)
78+
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4))
6479
}
6580

6681
if (state.isExitDialogVisible) {
@@ -79,107 +94,12 @@ internal fun RecordRegister(
7994
}
8095
}
8196

82-
@Composable
83-
internal fun RecordRegisterContent(
84-
state: RecordUiState,
85-
modifier: Modifier = Modifier,
86-
) {
87-
val focusManager = LocalFocusManager.current
88-
89-
Column(
90-
modifier = modifier
91-
.fillMaxSize()
92-
.background(White)
93-
.padding(horizontal = ReedTheme.spacing.spacing5),
94-
) {
95-
RecordProgressBar(
96-
currentStep = RecordStep.REGISTER,
97-
modifier = modifier,
98-
)
99-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing10))
100-
Text(
101-
text = stringResource(R.string.record_register_title1),
102-
color = ReedTheme.colors.contentPrimary,
103-
style = ReedTheme.typography.heading1Bold,
104-
)
105-
Text(
106-
text = stringResource(R.string.record_register_title2),
107-
color = ReedTheme.colors.contentPrimary,
108-
style = ReedTheme.typography.heading1Bold,
109-
)
110-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing10))
111-
Text(
112-
text = stringResource(R.string.record_page_label),
113-
color = ReedTheme.colors.contentPrimary,
114-
style = ReedTheme.typography.body1Medium,
115-
)
116-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
117-
ReedRecordTextField(
118-
recordState = state.recordPageState,
119-
recordHintRes = R.string.record_page_hint,
120-
keyboardOptions = KeyboardOptions(
121-
keyboardType = KeyboardType.Number,
122-
imeAction = ImeAction.Next,
123-
),
124-
lineLimits = TextFieldLineLimits.SingleLine,
125-
onClear = {
126-
state.eventSink(RecordRegisterUiEvent.OnClearClick)
127-
},
128-
onNext = {
129-
focusManager.moveFocus(FocusDirection.Down)
130-
},
131-
modifier = Modifier
132-
.fillMaxWidth()
133-
.height(50.dp),
134-
)
135-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing8))
136-
Text(
137-
text = stringResource(R.string.record_sentence_label),
138-
color = ReedTheme.colors.contentPrimary,
139-
style = ReedTheme.typography.body1Medium,
140-
)
141-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
142-
ReedRecordTextField(
143-
recordState = state.recordSentenceState,
144-
recordHintRes = R.string.record_sentence_hint,
145-
modifier = Modifier
146-
.fillMaxWidth()
147-
.height(140.dp),
148-
)
149-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing3))
150-
ReedButton(
151-
onClick = {},
152-
colorStyle = ReedButtonColorStyle.STROKE,
153-
sizeStyle = smallRoundedButtonStyle,
154-
modifier = Modifier.align(Alignment.End),
155-
text = stringResource(R.string.record_scan_sentence),
156-
leadingIcon = {
157-
Icon(
158-
imageVector = ImageVector.vectorResource(designR.drawable.ic_maximize),
159-
contentDescription = "Scan Icon",
160-
)
161-
},
162-
)
163-
Spacer(modifier = Modifier.weight(1f))
164-
ReedButton(
165-
onClick = {
166-
state.eventSink(RecordRegisterUiEvent.OnNextButtonClick)
167-
},
168-
colorStyle = ReedButtonColorStyle.PRIMARY,
169-
sizeStyle = largeButtonStyle,
170-
modifier = Modifier.fillMaxWidth(),
171-
text = stringResource(R.string.record_next_button),
172-
)
173-
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4))
174-
}
175-
}
176-
17797
@DevicePreview
17898
@Composable
17999
private fun RecordRegisterPreview() {
180100
ReedTheme {
181101
RecordRegister(
182-
state = RecordUiState(
102+
state = RecordRegisterUiState(
183103
eventSink = {},
184104
),
185105
)

feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUiState.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.ninecraft.booket.feature.record.register
22

33
import androidx.compose.foundation.text.input.TextFieldState
4+
import com.ninecraft.booket.core.designsystem.RecordStep
45
import com.slack.circuit.runtime.CircuitUiEvent
56
import com.slack.circuit.runtime.CircuitUiState
67

7-
data class RecordUiState(
8+
data class RecordRegisterUiState(
9+
val currentStep: RecordStep = RecordStep.QUOTE,
810
val recordPageState: TextFieldState = TextFieldState(),
911
val recordSentenceState: TextFieldState = TextFieldState(),
12+
val impressionState: TextFieldState = TextFieldState(),
1013
val isExitDialogVisible: Boolean = false,
1114
val eventSink: (RecordRegisterUiEvent) -> Unit,
1215
) : CircuitUiState

0 commit comments

Comments
 (0)