refactor BasePromptSettingsScreen to use InspiringSearchField and unify prompt settings across the app
This commit is contained in:
@@ -134,7 +134,9 @@ fun AppOutlinedTextField(
|
||||
fun InspiringSearchField(
|
||||
value: String,
|
||||
hints : Array<String>,
|
||||
onValueChange: (String) -> Unit
|
||||
onValueChange: (String) -> Unit,
|
||||
minLines: Int = 1,
|
||||
maxLines: Int = 1
|
||||
) {
|
||||
|
||||
var currentHintIndex by remember { mutableIntStateOf(0) }
|
||||
@@ -166,14 +168,14 @@ fun InspiringSearchField(
|
||||
Text(
|
||||
text = hint,
|
||||
color = Color.Gray.copy(alpha = 0.6f),
|
||||
maxLines = 1,
|
||||
//maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
minLines = 1,
|
||||
maxLines = 1
|
||||
minLines = minLines,
|
||||
maxLines = maxLines
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ fun AppCard(
|
||||
if (!title.isNullOrBlank()) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package eu.gaudian.translator.view.settings
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -9,7 +8,6 @@ import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
@@ -32,6 +30,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.gaudian.translator.R
|
||||
@@ -42,7 +41,7 @@ import eu.gaudian.translator.view.composable.AppButton
|
||||
import eu.gaudian.translator.view.composable.AppCard
|
||||
import eu.gaudian.translator.view.composable.AppIcons
|
||||
import eu.gaudian.translator.view.composable.AppOutlinedButton
|
||||
import eu.gaudian.translator.view.composable.AppOutlinedTextField
|
||||
import eu.gaudian.translator.view.composable.InspiringSearchField
|
||||
import eu.gaudian.translator.view.composable.ModelBadges
|
||||
|
||||
data class PromptSettingsState(
|
||||
@@ -55,13 +54,14 @@ data class PromptSettingsState(
|
||||
@Composable
|
||||
fun BasePromptSettingsScreen(
|
||||
state: PromptSettingsState,
|
||||
providers: List<ApiProvider>, // Pass the list of providers
|
||||
providers: List<ApiProvider>,
|
||||
description: String,
|
||||
onPromptChanged: (String) -> Unit,
|
||||
onSaveClicked: () -> Unit,
|
||||
onModelSelected: (LanguageModel?) -> Unit,
|
||||
onExamplePromptClicked: (String) -> Unit
|
||||
hints: Array<String>
|
||||
) {
|
||||
AppCard {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -73,16 +73,15 @@ fun BasePromptSettingsScreen(
|
||||
modifier = Modifier.padding(vertical = 16.dp)
|
||||
)
|
||||
|
||||
AppCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
|
||||
Column(Modifier.padding(16.dp)) {
|
||||
AppOutlinedTextField(
|
||||
InspiringSearchField(
|
||||
value = state.customPrompt,
|
||||
onValueChange = onPromptChanged,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = { Text(stringResource(id = R.string.text_enter_your_custom_prompt)) },
|
||||
minLines = 3
|
||||
//label = { Text(stringResource(id = R.string.text_enter_your_custom_prompt)) },
|
||||
minLines = 3,
|
||||
maxLines = 5,
|
||||
hints = hints,
|
||||
)
|
||||
|
||||
Row(
|
||||
@@ -109,26 +108,9 @@ fun BasePromptSettingsScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.text_example_prompts),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
|
||||
state.examplePrompts.forEach { prompt ->
|
||||
Text(
|
||||
text = prompt,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onExamplePromptClicked(prompt) }
|
||||
.padding(vertical = 8.dp)
|
||||
)
|
||||
HorizontalDivider()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +256,7 @@ fun ApiModelDropDown(
|
||||
Text(
|
||||
text = providerName,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
fontWeight = androidx.compose.ui.text.font.FontWeight.Medium,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = if (isActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
|
||||
)
|
||||
Text(
|
||||
@@ -305,7 +287,7 @@ fun ApiModelDropDown(
|
||||
text = model.displayName,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.weight(1f),
|
||||
fontWeight = if (model == selectedModel) androidx.compose.ui.text.font.FontWeight.Medium else androidx.compose.ui.text.font.FontWeight.Normal
|
||||
fontWeight = if (model == selectedModel) FontWeight.Medium else FontWeight.Normal
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
ModelBadges(
|
||||
@@ -387,5 +369,6 @@ fun BasePromptSettingsScreenPreview() {
|
||||
onPromptChanged = {},
|
||||
onSaveClicked = {},
|
||||
onModelSelected = {},
|
||||
onExamplePromptClicked = {})
|
||||
hints = listOf("test1", "test2").toTypedArray(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@@ -82,7 +83,7 @@ fun CustomVocabularyPromptScreen(
|
||||
onPromptChanged = { tempPrompt = it },
|
||||
onSaveClicked = { settingsViewModel.saveCustomVocabularyPrompt(tempPrompt) },
|
||||
onModelSelected = { apiViewModel.setVocabularyModel(it) },
|
||||
onExamplePromptClicked = { tempPrompt = it }
|
||||
hints = stringArrayResource(R.array.vocabulary_example_prompts),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,12 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -34,11 +32,9 @@ import eu.gaudian.translator.utils.findActivity
|
||||
import eu.gaudian.translator.view.LocalShowExperimentalFeatures
|
||||
import eu.gaudian.translator.view.composable.AppCard
|
||||
import eu.gaudian.translator.view.composable.AppIcons
|
||||
import eu.gaudian.translator.view.composable.AppOutlinedTextField
|
||||
import eu.gaudian.translator.view.composable.AppScaffold
|
||||
import eu.gaudian.translator.view.composable.AppTopAppBar
|
||||
import eu.gaudian.translator.view.composable.OptionItemSwitch
|
||||
import eu.gaudian.translator.view.composable.PrimaryButton
|
||||
import eu.gaudian.translator.view.dictionary.DictionaryManagerContent
|
||||
import eu.gaudian.translator.view.hints.getDictionaryOptionsHint
|
||||
import eu.gaudian.translator.viewmodel.ApiViewModel
|
||||
@@ -113,51 +109,32 @@ fun DictionaryOptionsScreen(
|
||||
}
|
||||
|
||||
item {
|
||||
AppCard {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.text_ai_model_custom_prompt),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
ApiModelDropDown(
|
||||
models = availableModels,
|
||||
providers = allProviders,
|
||||
selectedModel = selectedModel,
|
||||
onModelSelected = { model ->
|
||||
apiViewModel.setDictionaryModel(model)
|
||||
},
|
||||
)
|
||||
AppOutlinedTextField(
|
||||
value = tempPrompt,
|
||||
onValueChange = { tempPrompt = it },
|
||||
label = { Text(stringResource(R.string.text_custom_dictionary_prompt)) },
|
||||
modifier = Modifier.defaultMinSize(minHeight = 120.dp)
|
||||
)
|
||||
PrimaryButton(
|
||||
onClick = { settingsViewModel.saveCustomPromptDictionary(tempPrompt) },
|
||||
text = stringResource(R.string.text_save_prompt),
|
||||
modifier = Modifier.align(Alignment.End)
|
||||
)
|
||||
}
|
||||
}
|
||||
val screenState = PromptSettingsState(
|
||||
availableModels = availableModels,
|
||||
selectedModel = selectedModel,
|
||||
customPrompt = tempPrompt,
|
||||
examplePrompts = emptyList()
|
||||
)
|
||||
|
||||
BasePromptSettingsScreen(
|
||||
state = screenState,
|
||||
providers = allProviders,
|
||||
description = stringResource(R.string.text_description_dictionary_prompt),
|
||||
onPromptChanged = { tempPrompt = it },
|
||||
onSaveClicked = { settingsViewModel.saveCustomPromptDictionary(tempPrompt) },
|
||||
onModelSelected = { apiViewModel.setDictionaryModel(it) },
|
||||
hints = emptyArray(), //TODO
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
AppCard {
|
||||
|
||||
AppCard (
|
||||
AppCard(
|
||||
title = stringResource(R.string.label_dictionary_content),
|
||||
text = stringResource(R.string.text_select_the_content_dictionary),
|
||||
expandable = true,
|
||||
initiallyExpanded = false,
|
||||
|
||||
){
|
||||
) {
|
||||
Column(Modifier.padding(0.dp)) {
|
||||
|
||||
|
||||
dictionaryOptionKeys.zip(dictionaryOptionLabels).forEach { (key, label) ->
|
||||
val isChecked = dictionarySwitches.contains(key) || dictionarySwitches.contains(label)
|
||||
|
||||
@@ -182,7 +159,6 @@ fun DictionaryOptionsScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
@@ -104,11 +104,11 @@ fun TranslationSettingsScreen(
|
||||
BasePromptSettingsScreen(
|
||||
state = screenState,
|
||||
providers = allProviders,
|
||||
description = stringResource(R.string.text_here_you_can_set),
|
||||
description = stringResource(R.string.text_translation_instructions),
|
||||
onPromptChanged = { tempPrompt = it },
|
||||
onSaveClicked = { settingsViewModel.saveCustomPrompt(tempPrompt) },
|
||||
onModelSelected = { apiViewModel.setTranslationModel(it) },
|
||||
onExamplePromptClicked = { tempPrompt = it }
|
||||
hints = context.resources.getStringArray(R.array.example_prompts),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user