Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assistant Screen UI Improvements #14675

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,16 @@ class AssistantViewModel(
viewModelScope.launch(Dispatchers.IO) {
val taskTypesResult = repository.getTaskTypes()

if (taskTypesResult.isNullOrEmpty()) {
if (taskTypesResult == null) {
updateSnackbarMessage(R.string.assistant_screen_task_types_error_state_message)
return@launch
}

if (taskTypesResult.isEmpty()) {
updateSnackbarMessage(R.string.assistant_screen_task_list_empty_message)
return@launch
}

_taskTypes.update {
taskTypesResult
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,6 @@ private fun EmptyTaskList(
taskTypes: List<TaskTypeData>?,
viewModel: AssistantViewModel
) {
val text = stringResource(
id = R.string.assistant_screen_no_task_available_text,
selectedTaskType?.name ?: ""
)

Column(
modifier = Modifier
.fillMaxSize()
Expand All @@ -280,7 +275,11 @@ private fun EmptyTaskList(
Spacer(modifier = Modifier.height(8.dp))
}

CenterText(text = text)
CenterText(
text = stringResource(
id = R.string.assistant_screen_create_a_new_task_from_bottom_right_text
)
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,23 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.nextcloud.client.assistant.extensions.getModifiedAtRepresentation
import com.nextcloud.client.assistant.extensions.getStatusIcon
import com.owncloud.android.R
import com.owncloud.android.lib.resources.assistant.v2.model.Task
import com.owncloud.android.lib.resources.assistant.v2.model.TaskInput
import com.owncloud.android.lib.resources.assistant.v2.model.TaskOutput
import com.owncloud.android.lib.resources.status.OCCapability
import java.util.concurrent.TimeUnit

@Composable
fun TaskStatusView(task: Task, foregroundColor: Color, capability: OCCapability) {
fun TaskStatusView(task: Task, capability: OCCapability) {
val context = LocalContext.current

Row(
Expand All @@ -50,13 +51,13 @@ fun TaskStatusView(task: Task, foregroundColor: Color, capability: OCCapability)
Image(
painter = painterResource(id = iconId),
modifier = Modifier.size(16.dp),
colorFilter = ColorFilter.tint(foregroundColor),
colorFilter = ColorFilter.tint(color = colorResource(R.color.text_color)),
contentDescription = "status icon"
)

description?.let {
Spacer(modifier = Modifier.width(6.dp))
Text(text = description, color = foregroundColor)
Text(text = description, color = colorResource(R.color.text_color))
}
}
}
Expand Down Expand Up @@ -141,7 +142,6 @@ private fun TaskStatusViewPreview() {
items(tasks) {
TaskStatusView(
it,
foregroundColor = Color.White,
OCCapability().apply {
versionMayor = 30
}
Expand Down
25 changes: 10 additions & 15 deletions app/src/main/java/com/nextcloud/client/assistant/task/TaskView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.nextcloud.client.assistant.taskDetail.TaskDetailBottomSheet
import com.nextcloud.utils.extensions.truncateWithEllipsis
import com.owncloud.android.R
import com.owncloud.android.lib.resources.assistant.v2.model.Task
import com.owncloud.android.lib.resources.assistant.v2.model.TaskInput
Expand All @@ -56,7 +56,7 @@ fun TaskView(task: Task, capability: OCCapability, showTaskActions: () -> Unit)
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(8.dp))
.background(colorResource(R.color.primary))
.background(color = colorResource(R.color.task_container))
.clickable {
showTaskDetailBottomSheet = true
}
Expand All @@ -66,10 +66,11 @@ fun TaskView(task: Task, capability: OCCapability, showTaskActions: () -> Unit)

task.input?.input?.let {
Text(
text = it,
color = Color.White,
text = it.truncateWithEllipsis(30),
color = colorResource(R.color.text_color),
fontSize = 18.sp,
textAlign = TextAlign.Left,
maxLines = 1,
fontWeight = FontWeight.Bold,
modifier = Modifier.width(300.dp)
)
Expand All @@ -78,16 +79,10 @@ fun TaskView(task: Task, capability: OCCapability, showTaskActions: () -> Unit)
Spacer(modifier = Modifier.height(12.dp))

task.output?.output?.let {
val output = if (it.length >= 100) {
it.take(100) + "..."
} else {
it
}

Text(
text = output,
text = it.truncateWithEllipsis(100),
fontSize = 18.sp,
color = Color.White,
color = colorResource(R.color.text_color),
textAlign = TextAlign.Left,
modifier = Modifier
.animateContentSize(
Expand All @@ -99,10 +94,10 @@ fun TaskView(task: Task, capability: OCCapability, showTaskActions: () -> Unit)
)
}

TaskStatusView(task, foregroundColor = Color.White, capability)
TaskStatusView(task, capability)

if (showTaskDetailBottomSheet) {
TaskDetailBottomSheet(task, capability, showTaskActions = {
TaskDetailBottomSheet(task, showTaskActions = {
showTaskDetailBottomSheet = false
showTaskActions()
}) {
Expand All @@ -118,7 +113,7 @@ fun TaskView(task: Task, capability: OCCapability, showTaskActions: () -> Unit)
Icon(
imageVector = Icons.Filled.MoreVert,
contentDescription = "More button",
tint = Color.White
tint = colorResource(R.color.text_color)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,45 @@

package com.nextcloud.client.assistant.taskDetail

import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
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.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
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.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.nextcloud.client.assistant.task.TaskStatusView
import com.nextcloud.utils.extensions.getRandomString
import com.owncloud.android.R
import com.owncloud.android.lib.resources.assistant.v2.model.Task
import com.owncloud.android.lib.resources.assistant.v2.model.TaskInput
import com.owncloud.android.lib.resources.assistant.v2.model.TaskOutput
import com.owncloud.android.lib.resources.status.OCCapability

@Suppress("LongMethod")
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun TaskDetailBottomSheet(task: Task, capability: OCCapability, showTaskActions: () -> Unit, dismiss: () -> Unit) {
var showInput by remember { mutableStateOf(true) }
fun TaskDetailBottomSheet(task: Task, showTaskActions: () -> Unit, dismiss: () -> Unit) {
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)

ModalBottomSheet(
Expand Down Expand Up @@ -84,88 +73,56 @@ fun TaskDetailBottomSheet(task: Task, capability: OCCapability, showTaskActions:
)
}
}

Row(
modifier = Modifier
.fillMaxWidth()
.background(
color = colorResource(id = R.color.light_grey),
shape = RoundedCornerShape(8.dp)
)
) {
TextInputSelectButton(
Modifier.weight(1f),
R.string.assistant_task_detail_screen_input_button_title,
showInput,
onClick = {
showInput = true
}
)

TextInputSelectButton(
Modifier.weight(1f),
R.string.assistant_task_detail_screen_output_button_title,
!showInput,
onClick = {
showInput = false
}
)
}
}

item {
Spacer(modifier = Modifier.height(16.dp))
InputOutputCard(task)
}
}
}
}

Column(
modifier = Modifier
.fillMaxSize()
.background(
color = MaterialTheme.colorScheme.secondaryContainer,
shape = RoundedCornerShape(8.dp)
)
.padding(16.dp)
) {
Text(
text = if (showInput) {
task.input?.input ?: ""
} else {
task.output?.output ?: stringResource(R.string.assistant_screen_task_output_empty_text)
},
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier
.animateContentSize(
animationSpec = spring(
dampingRatio = Spring.DampingRatioLowBouncy,
stiffness = Spring.StiffnessLow
)
)
)
}
@Composable
fun InputOutputCard(task: Task) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.Transparent, shape = RoundedCornerShape(8.dp))
) {
TitleDescriptionBox(
title = stringResource(R.string.assistant_task_detail_screen_input_button_title),
description = task.input?.input ?: ""
)

TaskStatusView(task, foregroundColor = colorResource(R.color.text_color), capability)
Spacer(modifier = Modifier.height(16.dp))

Spacer(modifier = Modifier.height(32.dp))
}
}
TitleDescriptionBox(
title = stringResource(R.string.assistant_task_detail_screen_output_button_title),
description = task.output?.output ?: stringResource(R.string.assistant_screen_task_output_empty_text)
)
}
}

@Composable
private fun TextInputSelectButton(modifier: Modifier, titleId: Int, highlightCondition: Boolean, onClick: () -> Unit) {
Button(
onClick = onClick,
shape = RoundedCornerShape(8.dp),
colors = if (highlightCondition) {
ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary)
} else {
ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.secondary)
},
modifier = modifier
.widthIn(min = 0.dp, max = 200.dp)
.padding(horizontal = 4.dp)
private fun TitleDescriptionBox(title: String, description: String?) {
Text(
text = title,
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
color = colorResource(R.color.text_color)
)

Box(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
.background(color = colorResource(R.color.task_container), RoundedCornerShape(8.dp))
.padding(12.dp)
) {
Text(text = stringResource(id = titleId), color = MaterialTheme.colorScheme.surface)
Text(
text = description ?: "",
color = colorResource(R.color.text_color)
)
}
}

Expand All @@ -188,9 +145,6 @@ private fun TaskDetailScreenPreview() {
1707692337,
1707692337
),
OCCapability().apply {
versionMayor = 30
},
showTaskActions = {
}
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ fun String.removeFileExtension(): String {
}
}

fun String.truncateWithEllipsis(limit: Int) = take(limit) + if (length > limit) StringConstants.THREE_DOT else ""

object StringConstants {
const val SLASH = "/"
const val DOT = "."
const val SPACE = " "
const val THREE_DOT = "..."
}

fun String.getContentOfPublicKey(): String {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<color name="disabled_text">#ff6F6F6F</color>
<color name="secondary_text_color">#A5A5A5</color>
<color name="list_divider_background">#222222</color>
<color name="task_container">#222222</color>

<!-- Colors -->
<color name="dark">#ffffff</color>
Expand Down
Loading
Loading