From 8c981ca00488a301b992c9c21dc5bbf6064e2626 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 3 Mar 2026 10:59:10 +0100 Subject: [PATCH 1/7] feat(assistant): handle process text Signed-off-by: alperozturk96 --- .../client/assistant/AssistantScreen.kt | 60 +++++++----- .../conversation/ConversationScreen.kt | 2 +- .../assistant/model/ScreenOverlayState.kt | 2 + .../alertDialog/SimpleAlertDialog.kt | 8 +- .../alertDialog/TaskSelectionAlertDialog.kt | 96 +++++++++++++++++++ .../bottomSheet/MoreActionsBottomSheet.kt | 6 +- app/src/main/res/values/strings.xml | 1 + 7 files changed, 143 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt diff --git a/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt b/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt index 14a3a4b70c71..3a530da936ec 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt @@ -71,6 +71,7 @@ import com.nextcloud.client.assistant.translate.TranslationViewModel import com.nextcloud.ui.composeActivity.ComposeActivity import com.nextcloud.ui.composeActivity.ComposeViewModel import com.nextcloud.ui.composeComponents.alertDialog.SimpleAlertDialog +import com.nextcloud.ui.composeComponents.alertDialog.TaskSelectionAlertDialog import com.nextcloud.ui.composeComponents.bottomSheet.MoreActionsBottomSheet import com.nextcloud.utils.extensions.getChat import com.owncloud.android.R @@ -116,8 +117,8 @@ fun AssistantScreen( } LaunchedEffect(selectedText) { - selectedText?.let { - if (it.isBlank()) { + selectedText?.let { copiedText -> + if (copiedText.isBlank()) { return@LaunchedEffect } @@ -125,8 +126,10 @@ fun AssistantScreen( pagerState.scrollToPage(AssistantPage.Content.id) } - viewModel.updateInputBarText(it) - snackbarHostState.showSnackbar(activity.getString(R.string.assistant_screen_text_selected)) + taskTypes?.let { taskTypes -> + viewModel.updateScreenOverlayState(ScreenOverlayState.TaskTypes(copiedText, taskTypes)) + snackbarHostState.showSnackbar(activity.getString(R.string.assistant_screen_text_selected)) + } } } @@ -367,29 +370,38 @@ private fun InputBar(sessionId: Long?, selectedTaskType: TaskTypeData?, viewMode @Suppress("LongMethod") @Composable private fun OverlayState(state: ScreenOverlayState?, activity: Activity, viewModel: AssistantViewModel) { - when (state) { - is ScreenOverlayState.DeleteTask -> { - SimpleAlertDialog( - title = stringResource(id = R.string.assistant_screen_delete_task_alert_dialog_title), - description = stringResource(id = R.string.assistant_screen_delete_task_alert_dialog_description), - dismiss = { viewModel.updateScreenOverlayState(null) }, - onComplete = { viewModel.deleteTask(state.id) } - ) - } + state?.let { + when (state) { + is ScreenOverlayState.DeleteTask -> { + SimpleAlertDialog( + title = stringResource(id = R.string.assistant_screen_delete_task_alert_dialog_title), + description = stringResource(id = R.string.assistant_screen_delete_task_alert_dialog_description), + onDismiss = { viewModel.updateScreenOverlayState(null) }, + onComplete = { viewModel.deleteTask(state.id) } + ) + } - is ScreenOverlayState.TaskActions -> { - val actions = state.getActions(activity, onDeleteCompleted = { deleteTask -> - viewModel.updateScreenOverlayState(deleteTask) - }) + is ScreenOverlayState.TaskActions -> { + val actions = state.getActions(activity, onDeleteCompleted = { deleteTask -> + viewModel.updateScreenOverlayState(deleteTask) + }) - MoreActionsBottomSheet( - title = state.task.getInputTitle(), - actions = actions, - dismiss = { viewModel.updateScreenOverlayState(null) } - ) - } + MoreActionsBottomSheet( + title = state.task.getInputTitle(), + actions = actions, + onDismiss = { viewModel.updateScreenOverlayState(null) } + ) + } - else -> Unit + is ScreenOverlayState.TaskTypes -> { + TaskSelectionAlertDialog(state.taskTypes, onDismiss = { + viewModel.updateScreenOverlayState(null) + }, onConfirm = { + viewModel.selectTaskType(it) + viewModel.updateInputBarText(state.copiedText) + }) + } + } } } diff --git a/app/src/main/java/com/nextcloud/client/assistant/conversation/ConversationScreen.kt b/app/src/main/java/com/nextcloud/client/assistant/conversation/ConversationScreen.kt index 36ae8c1ee8f6..29e37fabade3 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/conversation/ConversationScreen.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/conversation/ConversationScreen.kt @@ -200,7 +200,7 @@ private fun ConversationList( MoreActionsBottomSheet( actions = bottomSheetAction, - dismiss = { selectedConversationId = -1L } + onDismiss = { selectedConversationId = -1L } ) } } diff --git a/app/src/main/java/com/nextcloud/client/assistant/model/ScreenOverlayState.kt b/app/src/main/java/com/nextcloud/client/assistant/model/ScreenOverlayState.kt index 76a100b60d96..5d63e66dab44 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/model/ScreenOverlayState.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/model/ScreenOverlayState.kt @@ -12,6 +12,7 @@ import com.nextcloud.client.assistant.extensions.getInputAndOutput import com.nextcloud.utils.extensions.showShareIntent import com.owncloud.android.R import com.owncloud.android.lib.resources.assistant.v2.model.Task +import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData import com.owncloud.android.utils.ClipboardUtil sealed class ScreenOverlayState { @@ -52,4 +53,5 @@ sealed class ScreenOverlayState { }) ) } + data class TaskTypes(val copiedText: String, val taskTypes: List) : ScreenOverlayState() } diff --git a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/SimpleAlertDialog.kt b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/SimpleAlertDialog.kt index bcf724e3dbd1..738c9ddc1bab 100644 --- a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/SimpleAlertDialog.kt +++ b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/SimpleAlertDialog.kt @@ -31,7 +31,7 @@ fun SimpleAlertDialog( heightFraction: Float? = null, content: @Composable (() -> Unit)? = null, onComplete: () -> Unit, - dismiss: () -> Unit + onDismiss: () -> Unit ) { val modifier = if (heightFraction != null) { Modifier @@ -46,7 +46,7 @@ fun SimpleAlertDialog( iconContentColor = MaterialTheme.colorScheme.onPrimaryContainer, titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer, textContentColor = MaterialTheme.colorScheme.onPrimaryContainer, - onDismissRequest = { dismiss() }, + onDismissRequest = { onDismiss() }, title = { Text(text = title) }, @@ -66,7 +66,7 @@ fun SimpleAlertDialog( confirmButton = { FilledTonalButton(onClick = { onComplete() - dismiss() + onDismiss() }) { Text( stringResource(id = R.string.common_ok) @@ -74,7 +74,7 @@ fun SimpleAlertDialog( } }, dismissButton = { - TextButton(onClick = { dismiss() }) { + TextButton(onClick = { onDismiss() }) { Text( stringResource(id = R.string.common_cancel) ) diff --git a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt new file mode 100644 index 000000000000..63049e0e89fb --- /dev/null +++ b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt @@ -0,0 +1,96 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.ui.composeComponents.alertDialog + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.owncloud.android.R +import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData + +@Composable +fun TaskSelectionAlertDialog(taskTypes: List, onDismiss: () -> Unit, onConfirm: (TaskTypeData) -> Unit) { + var tempSelectedTask by remember { + mutableStateOf(taskTypes.firstOrNull()) + } + + AlertDialog( + onDismissRequest = onDismiss, + title = { + Text( + text = stringResource(R.string.assistant_screen_select_task_type_title), + style = MaterialTheme.typography.titleLarge + ) + }, + text = { + LazyColumn(modifier = Modifier.fillMaxWidth()) { + items(taskTypes) { task -> + TaskTypeItem( + task = task, + isSelected = task.id == tempSelectedTask?.id, + onClick = { tempSelectedTask = task } + ) + } + } + }, + confirmButton = { + FilledTonalButton( + onClick = { + tempSelectedTask?.let { onConfirm(it) } + } + ) { + Text(text = stringResource(android.R.string.ok)) + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text(text = stringResource(android.R.string.cancel)) + } + } + ) +} + +@Composable +private fun TaskTypeItem(task: TaskTypeData, isSelected: Boolean, onClick: () -> Unit) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { onClick() } + .padding(vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + RadioButton( + selected = isSelected, + onClick = onClick + ) + Text( + text = task.name, + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(start = 12.dp), + color = MaterialTheme.colorScheme.onSurface + ) + } +} diff --git a/app/src/main/java/com/nextcloud/ui/composeComponents/bottomSheet/MoreActionsBottomSheet.kt b/app/src/main/java/com/nextcloud/ui/composeComponents/bottomSheet/MoreActionsBottomSheet.kt index b3d409aee0ca..94dd7c39b9b6 100644 --- a/app/src/main/java/com/nextcloud/ui/composeComponents/bottomSheet/MoreActionsBottomSheet.kt +++ b/app/src/main/java/com/nextcloud/ui/composeComponents/bottomSheet/MoreActionsBottomSheet.kt @@ -37,7 +37,7 @@ import kotlinx.coroutines.launch @SuppressLint("ResourceAsColor") @OptIn(ExperimentalMaterial3Api::class) @Composable -fun MoreActionsBottomSheet(title: String? = null, actions: List Unit>>, dismiss: () -> Unit) { +fun MoreActionsBottomSheet(title: String? = null, actions: List Unit>>, onDismiss: () -> Unit) { val sheetState = rememberModalBottomSheetState() val scope = rememberCoroutineScope() @@ -45,7 +45,7 @@ fun MoreActionsBottomSheet(title: String? = null, actions: ListDelete task Are you sure you want to delete this task? Delete Task + Select task Task created An error occurred while creating the task Task deleted From 3d543782b6d9633db5c630d2359f6a17b0706d29 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 3 Mar 2026 12:09:43 +0100 Subject: [PATCH 2/7] feat(assistant): handle process text Signed-off-by: alperozturk96 --- .../assistant/AssistantRepositoryTests.kt | 2 +- .../client/assistant/AssistantScreen.kt | 18 +++- .../client/assistant/AssistantViewModel.kt | 2 +- .../remote/AssistantRemoteRepository.kt | 2 +- .../remote/AssistantRemoteRepositoryImpl.kt | 2 +- .../remote/MockAssistantRemoteRepository.kt | 2 +- .../alertDialog/TaskSelectionAlertDialog.kt | 98 +++++++++++-------- app/src/main/res/values/strings.xml | 1 + 8 files changed, 78 insertions(+), 49 deletions(-) diff --git a/app/src/androidTest/java/com/nextcloud/client/assistant/AssistantRepositoryTests.kt b/app/src/androidTest/java/com/nextcloud/client/assistant/AssistantRepositoryTests.kt index 6d1c0475a46e..d2d333f4797f 100644 --- a/app/src/androidTest/java/com/nextcloud/client/assistant/AssistantRepositoryTests.kt +++ b/app/src/androidTest/java/com/nextcloud/client/assistant/AssistantRepositoryTests.kt @@ -35,7 +35,7 @@ class AssistantRepositoryTests : AbstractOnServerIT() { } runBlocking { - val result = sut?.getTaskTypes() + val result = sut?.fetchTaskTypes() assertTrue(result?.isNotEmpty() == true) } } diff --git a/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt b/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt index 3a530da936ec..863a6346b687 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/AssistantScreen.kt @@ -78,8 +78,10 @@ import com.owncloud.android.R import com.owncloud.android.lib.resources.assistant.v2.model.Task import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData import com.owncloud.android.lib.resources.status.OCCapability +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext private const val CHAT_INPUT_DELAY = 100L private const val PULL_TO_REFRESH_DELAY = 1500L @@ -126,9 +128,14 @@ fun AssistantScreen( pagerState.scrollToPage(AssistantPage.Content.id) } - taskTypes?.let { taskTypes -> - viewModel.updateScreenOverlayState(ScreenOverlayState.TaskTypes(copiedText, taskTypes)) - snackbarHostState.showSnackbar(activity.getString(R.string.assistant_screen_text_selected)) + scope.launch(Dispatchers.IO) { + val types = viewModel.getRemoteRepository().fetchTaskTypes() + if (!types.isNullOrEmpty()) { + withContext(Dispatchers.Main) { + viewModel.updateScreenOverlayState(ScreenOverlayState.TaskTypes(copiedText, types)) + snackbarHostState.showSnackbar(activity.getString(R.string.assistant_screen_text_selected)) + } + } } } } @@ -399,6 +406,11 @@ private fun OverlayState(state: ScreenOverlayState?, activity: Activity, viewMod }, onConfirm = { viewModel.selectTaskType(it) viewModel.updateInputBarText(state.copiedText) + + if (it.isTranslate()) { + viewModel.updateTranslationTaskState(true) + viewModel.updateScreenState(AssistantScreenState.Translation(null)) + } }) } } diff --git a/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt b/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt index 7bc212667745..74a231735b00 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt @@ -286,7 +286,7 @@ class AssistantViewModel( } private fun fetchTaskTypes() = viewModelScope.launch(Dispatchers.IO) { - val result = remoteRepository.getTaskTypes() + val result = remoteRepository.fetchTaskTypes() if (result.isNullOrEmpty()) { _screenState.value = AssistantScreenState.emptyTaskTypes() return@launch diff --git a/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepository.kt b/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepository.kt index 8b1f2397d421..4a578f6b512e 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepository.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepository.kt @@ -18,7 +18,7 @@ import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData import com.owncloud.android.lib.resources.assistant.v2.model.TranslationRequest interface AssistantRemoteRepository { - suspend fun getTaskTypes(): List? + suspend fun fetchTaskTypes(): List? suspend fun createTask(input: String, taskType: TaskTypeData): RemoteOperationResult diff --git a/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepositoryImpl.kt b/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepositoryImpl.kt index 923f689bd0e9..596e5353b3b9 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/repository/remote/AssistantRemoteRepositoryImpl.kt @@ -44,7 +44,7 @@ class AssistantRemoteRepositoryImpl(private val client: NextcloudClient, capabil private val supportsV2 = capability.version.isNewerOrEqual(NextcloudVersion.nextcloud_30) - override suspend fun getTaskTypes(): List? = withContext(Dispatchers.IO) { + override suspend fun fetchTaskTypes(): List? = withContext(Dispatchers.IO) { if (supportsV2) { val result = GetTaskTypesRemoteOperationV2().execute(client) if (result.isSuccess) { diff --git a/app/src/main/java/com/nextcloud/client/assistant/repository/remote/MockAssistantRemoteRepository.kt b/app/src/main/java/com/nextcloud/client/assistant/repository/remote/MockAssistantRemoteRepository.kt index e11ec5d1a873..0788cc4f8535 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/repository/remote/MockAssistantRemoteRepository.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/repository/remote/MockAssistantRemoteRepository.kt @@ -22,7 +22,7 @@ import com.owncloud.android.lib.resources.assistant.v2.model.TranslationRequest @Suppress("MagicNumber") class MockAssistantRemoteRepository(private val giveEmptyTasks: Boolean = false) : AssistantRemoteRepository { - override suspend fun getTaskTypes(): List = listOf( + override suspend fun fetchTaskTypes(): List = listOf( TaskTypeData( id = "core:text2text", name = "Free text to text prompt", diff --git a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt index 63049e0e89fb..4e78c8e72876 100644 --- a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt +++ b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt @@ -4,19 +4,19 @@ * SPDX-FileCopyrightText: 2026 Alper Ozturk * SPDX-License-Identifier: AGPL-3.0-or-later */ - package com.nextcloud.ui.composeComponents.alertDialog -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material3.AlertDialog +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuAnchorType +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.RadioButton +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable @@ -24,18 +24,18 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.owncloud.android.R import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData +@Suppress("LongMethod") +@OptIn(ExperimentalMaterial3Api::class) @Composable fun TaskSelectionAlertDialog(taskTypes: List, onDismiss: () -> Unit, onConfirm: (TaskTypeData) -> Unit) { - var tempSelectedTask by remember { - mutableStateOf(taskTypes.firstOrNull()) - } + var expanded by remember { mutableStateOf(false) } + var tempSelectedTask by remember { mutableStateOf(taskTypes.firstOrNull()) } AlertDialog( onDismissRequest = onDismiss, @@ -46,21 +46,59 @@ fun TaskSelectionAlertDialog(taskTypes: List, onDismiss: () -> Uni ) }, text = { - LazyColumn(modifier = Modifier.fillMaxWidth()) { - items(taskTypes) { task -> - TaskTypeItem( - task = task, - isSelected = task.id == tempSelectedTask?.id, - onClick = { tempSelectedTask = task } - ) + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { expanded = !expanded }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp) + ) { + OutlinedTextField( + value = tempSelectedTask?.name ?: "", + onValueChange = {}, + readOnly = true, + label = { Text(stringResource(R.string.assistant_screen_select_task_type_label)) }, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, + colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(), + modifier = Modifier + .menuAnchor( + type = ExposedDropdownMenuAnchorType.PrimaryNotEditable, + enabled = true + ) + .fillMaxWidth() + ) + + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false } + ) { + taskTypes.forEach { task -> + DropdownMenuItem( + text = { + Text( + text = task.name, + style = MaterialTheme.typography.bodyLarge + ) + }, + onClick = { + tempSelectedTask = task + expanded = false + }, + contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding + ) + } } } }, confirmButton = { FilledTonalButton( onClick = { - tempSelectedTask?.let { onConfirm(it) } - } + tempSelectedTask?.let { + onDismiss() + onConfirm(it) + } + }, + enabled = tempSelectedTask != null ) { Text(text = stringResource(android.R.string.ok)) } @@ -72,25 +110,3 @@ fun TaskSelectionAlertDialog(taskTypes: List, onDismiss: () -> Uni } ) } - -@Composable -private fun TaskTypeItem(task: TaskTypeData, isSelected: Boolean, onClick: () -> Unit) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onClick() } - .padding(vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - RadioButton( - selected = isSelected, - onClick = onClick - ) - Text( - text = task.name, - style = MaterialTheme.typography.bodyLarge, - modifier = Modifier.padding(start = 12.dp), - color = MaterialTheme.colorScheme.onSurface - ) - } -} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fdfa85f3e5ab..f064835307a1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -65,6 +65,7 @@ Are you sure you want to delete this task? Delete Task Select task + Task Task created An error occurred while creating the task Task deleted From 2a0db7c5a5857dda7d40db7ddf627120c7c7d67a Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 3 Mar 2026 12:11:31 +0100 Subject: [PATCH 3/7] feat(assistant): handle process text Signed-off-by: alperozturk96 --- .../java/com/nextcloud/client/assistant/AssistantViewModel.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt b/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt index 74a231735b00..8134df9fbe58 100644 --- a/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt +++ b/app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt @@ -379,6 +379,7 @@ class AssistantViewModel( } fun onTranslationScreenDismissed() { + updateInputBarText("") updateTranslationTaskState(false) selectTask(null) } From 278f579696fd645acb7649607139720803273b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alper=20=C3=96zt=C3=BCrk?= <67455295+alperozturk96@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:38:12 +0100 Subject: [PATCH 4/7] Update app/src/main/res/values/strings.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alper Öztürk <67455295+alperozturk96@users.noreply.github.com> --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f064835307a1..a2dc45009aa1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,7 +64,7 @@ Delete task Are you sure you want to delete this task? Delete Task - Select task + How can I help? Task Task created An error occurred while creating the task From dbbb6b7d0c0b4c9a813519ac322bb82a3ac14c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alper=20=C3=96zt=C3=BCrk?= <67455295+alperozturk96@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:38:17 +0100 Subject: [PATCH 5/7] Update app/src/main/res/values/strings.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alper Öztürk <67455295+alperozturk96@users.noreply.github.com> --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a2dc45009aa1..1107f22c1f9e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -65,7 +65,7 @@ Are you sure you want to delete this task? Delete Task How can I help? - Task + Choose an option Task created An error occurred while creating the task Task deleted From 7bcb0bdd57ad65552e5de6484f6bdc9b999d823f Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Mon, 9 Mar 2026 14:38:40 +0100 Subject: [PATCH 6/7] use dialog with buttons Signed-off-by: alperozturk96 --- .../alertDialog/TaskSelectionAlertDialog.kt | 112 +++++------------- 1 file changed, 28 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt index 4e78c8e72876..194a0c098664 100644 --- a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt +++ b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt @@ -6,107 +6,51 @@ */ package com.nextcloud.ui.composeComponents.alertDialog -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.DropdownMenuItem +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExposedDropdownMenuAnchorType -import androidx.compose.material3.ExposedDropdownMenuBox -import androidx.compose.material3.ExposedDropdownMenuDefaults -import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import com.owncloud.android.R +import androidx.compose.ui.window.Dialog import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData @Suppress("LongMethod") @OptIn(ExperimentalMaterial3Api::class) @Composable -fun TaskSelectionAlertDialog(taskTypes: List, onDismiss: () -> Unit, onConfirm: (TaskTypeData) -> Unit) { - var expanded by remember { mutableStateOf(false) } - var tempSelectedTask by remember { mutableStateOf(taskTypes.firstOrNull()) } - - AlertDialog( - onDismissRequest = onDismiss, - title = { - Text( - text = stringResource(R.string.assistant_screen_select_task_type_title), - style = MaterialTheme.typography.titleLarge - ) - }, - text = { - ExposedDropdownMenuBox( - expanded = expanded, - onExpandedChange = { expanded = !expanded }, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp) +fun TaskSelectionAlertDialog( + taskTypes: List, + onDismiss: () -> Unit, + onConfirm: (TaskTypeData) -> Unit +) { + Dialog(onDismissRequest = onDismiss) { + Surface( + shape = MaterialTheme.shapes.extraLarge, + tonalElevation = 6.dp + ) { + LazyColumn( + modifier = Modifier.padding(vertical = 16.dp) ) { - OutlinedTextField( - value = tempSelectedTask?.name ?: "", - onValueChange = {}, - readOnly = true, - label = { Text(stringResource(R.string.assistant_screen_select_task_type_label)) }, - trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, - colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(), - modifier = Modifier - .menuAnchor( - type = ExposedDropdownMenuAnchorType.PrimaryNotEditable, - enabled = true - ) - .fillMaxWidth() - ) - - ExposedDropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false } - ) { - taskTypes.forEach { task -> - DropdownMenuItem( - text = { - Text( - text = task.name, - style = MaterialTheme.typography.bodyLarge - ) - }, - onClick = { - tempSelectedTask = task - expanded = false - }, - contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding + items(taskTypes) { task -> + TextButton( + onClick = { + onConfirm(task) + onDismiss() + }, + modifier = Modifier.padding(horizontal = 8.dp) + ) { + Text( + text = task.name, + style = MaterialTheme.typography.bodyLarge ) } } } - }, - confirmButton = { - FilledTonalButton( - onClick = { - tempSelectedTask?.let { - onDismiss() - onConfirm(it) - } - }, - enabled = tempSelectedTask != null - ) { - Text(text = stringResource(android.R.string.ok)) - } - }, - dismissButton = { - TextButton(onClick = onDismiss) { - Text(text = stringResource(android.R.string.cancel)) - } } - ) + } } From ab69b7a1f9f4ed6a47e920abe128765f659a3def Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Mon, 9 Mar 2026 16:42:01 +0100 Subject: [PATCH 7/7] fix codacy Signed-off-by: alperozturk96 --- .../alertDialog/TaskSelectionAlertDialog.kt | 6 +----- app/src/main/res/values/strings.xml | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt index 194a0c098664..9cae1dd238fb 100644 --- a/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt +++ b/app/src/main/java/com/nextcloud/ui/composeComponents/alertDialog/TaskSelectionAlertDialog.kt @@ -23,11 +23,7 @@ import com.owncloud.android.lib.resources.assistant.v2.model.TaskTypeData @Suppress("LongMethod") @OptIn(ExperimentalMaterial3Api::class) @Composable -fun TaskSelectionAlertDialog( - taskTypes: List, - onDismiss: () -> Unit, - onConfirm: (TaskTypeData) -> Unit -) { +fun TaskSelectionAlertDialog(taskTypes: List, onDismiss: () -> Unit, onConfirm: (TaskTypeData) -> Unit) { Dialog(onDismissRequest = onDismiss) { Surface( shape = MaterialTheme.shapes.extraLarge, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1107f22c1f9e..f1965da59731 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,7 +64,6 @@ Delete task Are you sure you want to delete this task? Delete Task - How can I help? Choose an option Task created An error occurred while creating the task