Skip to content

Commit dbb9234

Browse files
committed
add translation logic
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent 63d83e5 commit dbb9234

3 files changed

Lines changed: 86 additions & 102 deletions

File tree

app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ fun AssistantScreen(
231231
}
232232

233233
AssistantScreenState.Translation -> {
234-
TranslationScreen(selectedTaskType, viewModel,selectedText ?: "")
234+
TranslationScreen(selectedTaskType, viewModel, selectedText ?: "")
235235
}
236236

237237
else -> EmptyContent(

app/src/main/java/com/nextcloud/client/assistant/translate/TranslationScreen.kt

Lines changed: 69 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -41,58 +41,51 @@ import com.nextcloud.client.assistant.AssistantViewModel
4141
import com.owncloud.android.R
4242
import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData
4343
import com.owncloud.android.lib.resources.assistant.v2.model.TranslationLanguage
44-
import com.owncloud.android.lib.resources.assistant.v2.model.TranslationLanguages
4544
import com.owncloud.android.lib.resources.assistant.v2.model.toTranslationLanguages
4645

4746
@OptIn(ExperimentalMaterial3Api::class)
4847
@Composable
4948
fun TranslationScreen(task: TaskTypeData?, viewModel: AssistantViewModel, textToTranslate: String) {
50-
var originText by remember { mutableStateOf(textToTranslate) }
51-
val languages = task?.toTranslationLanguages() ?: TranslationLanguages(listOf(), listOf())
49+
val languages = remember(task) { task?.toTranslationLanguages() }
5250

53-
var originLanguage by remember { mutableStateOf(languages.originLanguages.first()) }
54-
var showOriginDropdownMenu by remember { mutableStateOf(false) }
55-
56-
var targetText by remember { mutableStateOf("") }
57-
var targetLanguage by remember { mutableStateOf(languages.targetLanguages.first()) }
58-
var showTargetDropdownMenu by remember { mutableStateOf(false) }
51+
var sourceState by remember {
52+
mutableStateOf(
53+
TranslationSideState(
54+
text = textToTranslate,
55+
language = languages?.originLanguages?.firstOrNull()
56+
)
57+
)
58+
}
59+
var targetState by remember {
60+
mutableStateOf(TranslationSideState(language = languages?.targetLanguages?.firstOrNull()))
61+
}
5962

6063
Scaffold(
6164
modifier = Modifier
6265
.fillMaxSize()
6366
.padding(16.dp)
64-
.padding(top = 32.dp), floatingActionButton = {
67+
.padding(top = 32.dp),
68+
floatingActionButton = {
6569
FloatingActionButton(onClick = {
66-
viewModel.translate(textToTranslate, originLanguage, targetLanguage)
70+
val originLang = sourceState.language
71+
val targetLang = targetState.language
72+
if (originLang != null && targetLang != null) {
73+
viewModel.translate(sourceState.text, originLang, targetLang)
74+
}
6775
}, content = {
68-
Icon(
69-
painter = painterResource(R.drawable.ic_translate),
70-
contentDescription = "translate button"
71-
)
76+
Icon(painter = painterResource(R.drawable.ic_translate), contentDescription = "translate button")
7277
})
73-
}) {
74-
LazyColumn(
75-
modifier = Modifier.padding(it)
76-
) {
78+
}
79+
) { paddingValues ->
80+
LazyColumn(modifier = Modifier.padding(paddingValues)) {
7781
item {
78-
LanguageSelector(
79-
title = originLanguage,
80-
languages = languages.originLanguages,
81-
titleId = R.string.translation_screen_label_from,
82-
expanded = showOriginDropdownMenu,
83-
expand = {
84-
showOriginDropdownMenu = it
85-
}, onLanguageSelect = { newLanguage ->
86-
originLanguage = newLanguage
87-
}
82+
TranslationSection(
83+
labelId = R.string.translation_screen_label_from,
84+
hintId = R.string.translation_screen_hint_source,
85+
state = sourceState,
86+
availableLanguages = languages?.originLanguages ?: emptyList(),
87+
onStateChange = { sourceState = it }
8888
)
89-
90-
TranslationTextField(
91-
titleId = R.string.translation_screen_hint_source,
92-
originText,
93-
onValueChange = { updatedText ->
94-
originText = updatedText
95-
})
9689
}
9790

9891
item {
@@ -104,98 +97,73 @@ fun TranslationScreen(task: TaskTypeData?, viewModel: AssistantViewModel, textTo
10497
}
10598

10699
item {
107-
LanguageSelector(
108-
title = targetLanguage,
109-
languages = languages.targetLanguages,
110-
titleId = R.string.translation_screen_label_to,
111-
expanded = showTargetDropdownMenu,
112-
expand = {
113-
showTargetDropdownMenu = it
114-
}, onLanguageSelect = { newLanguage ->
115-
targetLanguage = newLanguage
116-
}
100+
TranslationSection(
101+
labelId = R.string.translation_screen_label_to,
102+
hintId = R.string.translation_screen_hint_target,
103+
state = targetState,
104+
availableLanguages = languages?.targetLanguages ?: emptyList(),
105+
onStateChange = { targetState = it }
117106
)
118-
119-
TranslationTextField(
120-
titleId = R.string.translation_screen_hint_target,
121-
targetText,
122-
onValueChange = { updatedText ->
123-
targetText = updatedText
124-
})
125107
}
126108
}
127109
}
128110
}
129111

130112
@Composable
131-
private fun TranslationTextField(titleId: Int, value: String, onValueChange: (String) -> Unit) {
132-
TextField(
133-
value = value,
134-
onValueChange = {
135-
onValueChange(it)
136-
},
137-
modifier = Modifier
138-
.fillMaxWidth()
139-
.heightIn(min = 120.dp, max = 240.dp),
140-
placeholder = {
141-
Text(
142-
text = stringResource(titleId),
143-
style = MaterialTheme.typography.headlineSmall
144-
)
145-
},
146-
textStyle = MaterialTheme.typography.headlineSmall,
147-
colors = TextFieldDefaults.colors(
148-
focusedContainerColor = Color.Transparent,
149-
unfocusedContainerColor = Color.Transparent,
150-
disabledContainerColor = Color.Transparent,
151-
focusedIndicatorColor = Color.Transparent,
152-
unfocusedIndicatorColor = Color.Transparent
153-
)
154-
)
155-
}
156-
157-
@Composable
158-
private fun LanguageSelector(
159-
title: TranslationLanguage,
160-
languages: List<TranslationLanguage>,
161-
titleId: Int,
162-
expanded: Boolean,
163-
expand: (Boolean) -> Unit,
164-
onLanguageSelect: (TranslationLanguage) -> Unit
113+
private fun TranslationSection(
114+
labelId: Int,
115+
hintId: Int,
116+
state: TranslationSideState,
117+
availableLanguages: List<TranslationLanguage>,
118+
onStateChange: (TranslationSideState) -> Unit
165119
) {
166120
Row(
167121
modifier = Modifier
168122
.padding(16.dp)
169-
.clickable(onClick = {
170-
expand(!expanded)
171-
})
123+
.clickable { onStateChange(state.copy(isExpanded = !state.isExpanded)) }
172124
) {
173125
Text(
174-
text = stringResource(titleId),
126+
text = stringResource(labelId),
175127
style = MaterialTheme.typography.labelLarge,
176-
color = MaterialTheme.colorScheme.primary,
128+
color = MaterialTheme.colorScheme.primary
177129
)
178-
179130
Spacer(modifier = Modifier.width(8.dp))
180-
181131
Text(
182-
text = title.name,
183-
style = MaterialTheme.typography.labelLarge,
132+
text = state.language?.name ?: "",
133+
style = MaterialTheme.typography.labelLarge
184134
)
185135

186136
DropdownMenu(
187-
expanded = expanded,
188-
onDismissRequest = { expand(false) }
137+
expanded = state.isExpanded,
138+
onDismissRequest = { onStateChange(state.copy(isExpanded = false)) }
189139
) {
190-
languages.forEach { language ->
140+
availableLanguages.forEach { language ->
191141
DropdownMenuItem(
192142
text = { Text(language.name) },
193143
onClick = {
194-
expand(false)
195-
onLanguageSelect(language)
144+
onStateChange(state.copy(language = language, isExpanded = false))
196145
}
197146
)
198147
}
199148
}
200149
}
150+
151+
TextField(
152+
value = state.text,
153+
onValueChange = { onStateChange(state.copy(text = it)) },
154+
modifier = Modifier
155+
.fillMaxWidth()
156+
.heightIn(min = 120.dp, max = 240.dp),
157+
placeholder = {
158+
Text(text = stringResource(hintId), style = MaterialTheme.typography.headlineSmall)
159+
},
160+
textStyle = MaterialTheme.typography.headlineSmall,
161+
colors = TextFieldDefaults.colors(
162+
focusedContainerColor = Color.Transparent,
163+
unfocusedContainerColor = Color.Transparent,
164+
disabledContainerColor = Color.Transparent,
165+
focusedIndicatorColor = Color.Transparent,
166+
unfocusedIndicatorColor = Color.Transparent
167+
)
168+
)
201169
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.nextcloud.client.assistant.translate
9+
10+
import com.owncloud.android.lib.resources.assistant.v2.model.TranslationLanguage
11+
12+
data class TranslationSideState(
13+
val text: String = "",
14+
val language: TranslationLanguage? = null,
15+
val isExpanded: Boolean = false
16+
)

0 commit comments

Comments
 (0)