Skip to content

Commit f1ebfa9

Browse files
authored
Merge pull request #62 from yml-org/feature/CM-1321/edits-screen-android
feature: implements edits screen on android sample
2 parents 6e32516 + bb24a36 commit f1ebfa9

File tree

4 files changed

+131
-9
lines changed

4 files changed

+131
-9
lines changed

sample/android/src/main/java/co/yml/ychat/android/di/AppModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import co.yml.ychat.YChat
44
import co.yml.ychat.android.BuildConfig
55
import co.yml.ychat.android.presentation.chatcompletions.viewmodel.ChatCompletionsViewModel
66
import co.yml.ychat.android.presentation.completions.CompletionsViewModel
7+
import co.yml.ychat.android.presentation.edits.EditsViewModel
78
import co.yml.ychat.android.presentation.home.viewmodel.HomeViewModel
89
import co.yml.ychat.android.presentation.models.viewmodel.ModelsViewModel
910
import org.koin.androidx.viewmodel.dsl.viewModelOf
@@ -15,4 +16,5 @@ val appModule = module {
1516
viewModelOf(::ChatCompletionsViewModel)
1617
viewModelOf(::ModelsViewModel)
1718
viewModelOf(::CompletionsViewModel)
19+
viewModelOf(::EditsViewModel)
1820
}
Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,75 @@
11
package co.yml.ychat.android.presentation.edits
22

33
import androidx.compose.foundation.background
4-
import androidx.compose.foundation.layout.Arrangement
54
import androidx.compose.foundation.layout.Column
6-
import androidx.compose.foundation.layout.fillMaxHeight
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.layout.padding
79
import androidx.compose.runtime.Composable
810
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.res.stringResource
912
import androidx.compose.ui.tooling.preview.Preview
10-
import co.yml.ychat.android.ui.components.feedback.Feedback
11-
import co.yml.ychat.android.ui.components.feedback.model.FeedbackState
13+
import androidx.compose.ui.unit.dp
14+
import co.yml.ychat.YChat
15+
import co.yml.ychat.android.BuildConfig
16+
import co.yml.ychat.android.R
17+
import co.yml.ychat.android.ui.components.button.ButtonContained
18+
import co.yml.ychat.android.ui.components.output.OutputBox
19+
import co.yml.ychat.android.ui.components.textfield.StandardTextField
20+
import co.yml.ychat.android.ui.theme.Dimens
21+
import co.yml.ychat.android.ui.theme.TypographyStyle
1222
import co.yml.ychat.android.ui.theme.YChatTheme
23+
import org.koin.androidx.compose.getViewModel
1324

1425
@Composable
15-
internal fun EditsScreen() {
26+
internal fun EditsScreen(viewModel: EditsViewModel = getViewModel()) {
1627
Column(
1728
modifier = Modifier
1829
.background(YChatTheme.colors.background)
19-
.fillMaxHeight(),
20-
verticalArrangement = Arrangement.Center,
30+
.padding(Dimens.MD)
31+
.fillMaxSize(),
2132
) {
22-
Feedback(feedbackState = FeedbackState.CONSTRUCTION)
33+
TypographyStyle.MediumBody.Text(text = stringResource(id = R.string.edits_input_title))
34+
StandardTextField(
35+
value = viewModel.inputMessage.value,
36+
hint = stringResource(id = R.string.edits_input_hint),
37+
modifier = Modifier
38+
.height(100.dp)
39+
.fillMaxWidth()
40+
.padding(top = Dimens.SM, bottom = Dimens.MD),
41+
onTextChanged = { viewModel.onInputMessage(it) },
42+
enabled = viewModel.onEnableTextField.value,
43+
)
44+
TypographyStyle.MediumBody.Text(text = stringResource(id = R.string.edits_instruction_title))
45+
StandardTextField(
46+
value = viewModel.instructionMessage.value,
47+
hint = stringResource(id = R.string.edits_instruction_hint),
48+
modifier = Modifier
49+
.fillMaxWidth()
50+
.padding(top = Dimens.SM, bottom = Dimens.XM)
51+
,
52+
onTextChanged = { viewModel.onInstructionMessage(it) },
53+
enabled = viewModel.onEnableTextField.value,
54+
)
55+
ButtonContained(
56+
text = stringResource(id = R.string.edits_action),
57+
modifier = Modifier
58+
.fillMaxWidth()
59+
.padding(vertical = Dimens.XM),
60+
enabled = viewModel.onEnableButton.value,
61+
onClick = { viewModel.requestEdits() }
62+
)
63+
OutputBox(outputBoxStates = viewModel.outputBoxStates)
2364
}
2465
}
2566

2667
@Preview
2768
@Composable
2869
private fun EditsScreenPreview() {
2970
YChatTheme {
30-
EditsScreen()
71+
val yChat = YChat.create(BuildConfig.API_KEY)
72+
val viewModel = EditsViewModel(yChat)
73+
EditsScreen(viewModel)
3174
}
3275
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package co.yml.ychat.android.presentation.edits
2+
3+
import androidx.compose.runtime.mutableStateListOf
4+
import androidx.compose.runtime.mutableStateOf
5+
import androidx.lifecycle.ViewModel
6+
import androidx.lifecycle.viewModelScope
7+
import co.yml.ychat.YChat
8+
import co.yml.ychat.android.ui.components.output.OutputBoxState
9+
import kotlinx.coroutines.launch
10+
11+
internal class EditsViewModel(private val yChat: YChat) : ViewModel() {
12+
13+
val inputMessage = mutableStateOf("")
14+
15+
val instructionMessage = mutableStateOf("")
16+
17+
val outputBoxStates = mutableStateListOf<OutputBoxState>()
18+
19+
val onEnableButton = mutableStateOf(false)
20+
21+
val onEnableTextField = mutableStateOf(true)
22+
23+
fun requestEdits() = viewModelScope.launch {
24+
outputBoxStates.clear()
25+
onLoading(true)
26+
val edits = yChat.edits()
27+
.setInput(inputMessage.value)
28+
.setResults(1)
29+
runCatching { edits.execute(instructionMessage.value) }
30+
.also { onLoading(false) }
31+
.onSuccess { outputBoxStates.add(OutputBoxState.Text(it.first())) }
32+
.onFailure { onError(true) }
33+
}
34+
35+
fun onInputMessage(message: String) {
36+
this.inputMessage.value = message
37+
onEnableButton()
38+
}
39+
40+
fun onInstructionMessage(message: String) {
41+
this.instructionMessage.value = message
42+
onEnableButton()
43+
}
44+
45+
private fun onEnableButton() {
46+
onEnableButton.value = inputMessage.value.isNotEmpty() &&
47+
instructionMessage.value.isNotEmpty()
48+
}
49+
50+
private fun onLoading(isLoading: Boolean) {
51+
if (isLoading) {
52+
onError(false)
53+
onEnableButton.value = false
54+
onEnableTextField.value = false
55+
outputBoxStates.add(OutputBoxState.Loading)
56+
} else {
57+
onEnableTextField.value = true
58+
outputBoxStates.remove(OutputBoxState.Loading)
59+
onEnableButton()
60+
}
61+
}
62+
63+
private fun onError(isError: Boolean) {
64+
if (isError) {
65+
outputBoxStates.add(OutputBoxState.Error)
66+
} else {
67+
outputBoxStates.remove(OutputBoxState.Error)
68+
}
69+
}
70+
}

sample/android/src/main/res/values/strings.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
<string name="completions_hint">Write a tagline for an ice cream shop.</string>
2020
<string name="completions_action">Submit</string>
2121

22+
<!-- EditsScreen -->
23+
<string name="edits_input_title">Input</string>
24+
<string name="edits_instruction_title">Instruction</string>
25+
<string name="edits_input_hint">We is going to the market.</string>
26+
<string name="edits_instruction_hint">Fix the grammar.</string>
27+
<string name="edits_action">Submit</string>
28+
2229
<!-- FeedbackState.ERROR -->
2330
<string name="feedback_state_error_title">Something went wrong</string>
2431
<string name="feedback_state_error_message">There was a problem with the request. Please try again in a few moments.</string>

0 commit comments

Comments
 (0)