diff --git a/sample/android/src/main/java/co/yml/ychat/android/di/AppModule.kt b/sample/android/src/main/java/co/yml/ychat/android/di/AppModule.kt index 3f63c15..0afe1a8 100644 --- a/sample/android/src/main/java/co/yml/ychat/android/di/AppModule.kt +++ b/sample/android/src/main/java/co/yml/ychat/android/di/AppModule.kt @@ -4,6 +4,7 @@ import co.yml.ychat.YChat import co.yml.ychat.android.BuildConfig import co.yml.ychat.android.presentation.chatcompletions.viewmodel.ChatCompletionsViewModel import co.yml.ychat.android.presentation.completions.CompletionsViewModel +import co.yml.ychat.android.presentation.edits.EditsViewModel import co.yml.ychat.android.presentation.home.viewmodel.HomeViewModel import co.yml.ychat.android.presentation.models.viewmodel.ModelsViewModel import org.koin.androidx.viewmodel.dsl.viewModelOf @@ -15,4 +16,5 @@ val appModule = module { viewModelOf(::ChatCompletionsViewModel) viewModelOf(::ModelsViewModel) viewModelOf(::CompletionsViewModel) + viewModelOf(::EditsViewModel) } \ No newline at end of file diff --git a/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsScreen.kt b/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsScreen.kt index 6d893c5..d400ec4 100644 --- a/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsScreen.kt +++ b/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsScreen.kt @@ -1,25 +1,66 @@ package co.yml.ychat.android.presentation.edits import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import co.yml.ychat.android.ui.components.feedback.Feedback -import co.yml.ychat.android.ui.components.feedback.model.FeedbackState +import androidx.compose.ui.unit.dp +import co.yml.ychat.YChat +import co.yml.ychat.android.BuildConfig +import co.yml.ychat.android.R +import co.yml.ychat.android.ui.components.button.ButtonContained +import co.yml.ychat.android.ui.components.output.OutputBox +import co.yml.ychat.android.ui.components.textfield.StandardTextField +import co.yml.ychat.android.ui.theme.Dimens +import co.yml.ychat.android.ui.theme.TypographyStyle import co.yml.ychat.android.ui.theme.YChatTheme +import org.koin.androidx.compose.getViewModel @Composable -internal fun EditsScreen() { +internal fun EditsScreen(viewModel: EditsViewModel = getViewModel()) { Column( modifier = Modifier .background(YChatTheme.colors.background) - .fillMaxHeight(), - verticalArrangement = Arrangement.Center, + .padding(Dimens.MD) + .fillMaxSize(), ) { - Feedback(feedbackState = FeedbackState.CONSTRUCTION) + TypographyStyle.MediumBody.Text(text = stringResource(id = R.string.edits_input_title)) + StandardTextField( + value = viewModel.inputMessage.value, + hint = stringResource(id = R.string.edits_input_hint), + modifier = Modifier + .height(100.dp) + .fillMaxWidth() + .padding(top = Dimens.SM, bottom = Dimens.MD), + onTextChanged = { viewModel.onInputMessage(it) }, + enabled = viewModel.onEnableTextField.value, + ) + TypographyStyle.MediumBody.Text(text = stringResource(id = R.string.edits_instruction_title)) + StandardTextField( + value = viewModel.instructionMessage.value, + hint = stringResource(id = R.string.edits_instruction_hint), + modifier = Modifier + .fillMaxWidth() + .padding(top = Dimens.SM, bottom = Dimens.XM) + , + onTextChanged = { viewModel.onInstructionMessage(it) }, + enabled = viewModel.onEnableTextField.value, + ) + ButtonContained( + text = stringResource(id = R.string.edits_action), + modifier = Modifier + .fillMaxWidth() + .padding(vertical = Dimens.XM), + enabled = viewModel.onEnableButton.value, + onClick = { viewModel.requestEdits() } + ) + OutputBox(outputBoxStates = viewModel.outputBoxStates) } } @@ -27,6 +68,8 @@ internal fun EditsScreen() { @Composable private fun EditsScreenPreview() { YChatTheme { - EditsScreen() + val yChat = YChat.create(BuildConfig.API_KEY) + val viewModel = EditsViewModel(yChat) + EditsScreen(viewModel) } } diff --git a/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsViewModel.kt b/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsViewModel.kt new file mode 100644 index 0000000..4ed39f5 --- /dev/null +++ b/sample/android/src/main/java/co/yml/ychat/android/presentation/edits/EditsViewModel.kt @@ -0,0 +1,70 @@ +package co.yml.ychat.android.presentation.edits + +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import co.yml.ychat.YChat +import co.yml.ychat.android.ui.components.output.OutputBoxState +import kotlinx.coroutines.launch + +internal class EditsViewModel(private val yChat: YChat) : ViewModel() { + + val inputMessage = mutableStateOf("") + + val instructionMessage = mutableStateOf("") + + val outputBoxStates = mutableStateListOf() + + val onEnableButton = mutableStateOf(false) + + val onEnableTextField = mutableStateOf(true) + + fun requestEdits() = viewModelScope.launch { + outputBoxStates.clear() + onLoading(true) + val edits = yChat.edits() + .setInput(inputMessage.value) + .setResults(1) + runCatching { edits.execute(instructionMessage.value) } + .also { onLoading(false) } + .onSuccess { outputBoxStates.add(OutputBoxState.Text(it.first())) } + .onFailure { onError(true) } + } + + fun onInputMessage(message: String) { + this.inputMessage.value = message + onEnableButton() + } + + fun onInstructionMessage(message: String) { + this.instructionMessage.value = message + onEnableButton() + } + + private fun onEnableButton() { + onEnableButton.value = inputMessage.value.isNotEmpty() && + instructionMessage.value.isNotEmpty() + } + + private fun onLoading(isLoading: Boolean) { + if (isLoading) { + onError(false) + onEnableButton.value = false + onEnableTextField.value = false + outputBoxStates.add(OutputBoxState.Loading) + } else { + onEnableTextField.value = true + outputBoxStates.remove(OutputBoxState.Loading) + onEnableButton() + } + } + + private fun onError(isError: Boolean) { + if (isError) { + outputBoxStates.add(OutputBoxState.Error) + } else { + outputBoxStates.remove(OutputBoxState.Error) + } + } +} \ No newline at end of file diff --git a/sample/android/src/main/res/values/strings.xml b/sample/android/src/main/res/values/strings.xml index ccd478f..77230ce 100644 --- a/sample/android/src/main/res/values/strings.xml +++ b/sample/android/src/main/res/values/strings.xml @@ -19,6 +19,13 @@ Write a tagline for an ice cream shop. Submit + + Input + Instruction + We is going to the market. + Fix the grammar. + Submit + Something went wrong There was a problem with the request. Please try again in a few moments.