Add 'Add task' button to Android Wear

Button doesn't do anything yet
pull/3070/head
Alex Baker 1 year ago
parent a8977f02fe
commit 3b60a5bcaf

@ -28,4 +28,5 @@
<string name="yesterday_lowercase">yesterday</string> <string name="yesterday_lowercase">yesterday</string>
<string name="today">Today</string> <string name="today">Today</string>
<string name="today_lowercase">today</string> <string name="today_lowercase">today</string>
<string name="add_task">Add task</string>
</resources> </resources>

@ -1,6 +1,7 @@
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android) alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.kotlin.compose.compiler) alias(libs.plugins.kotlin.compose.compiler)
} }
@ -42,10 +43,10 @@ android {
dependencies { dependencies {
coreLibraryDesugaring(libs.desugar.jdk.libs) coreLibraryDesugaring(libs.desugar.jdk.libs)
implementation(compose.components.resources)
implementation(projects.wearDatalayer) implementation(projects.wearDatalayer)
implementation(projects.kmp) implementation(projects.kmp)
implementation(libs.play.services.wearable) implementation(libs.play.services.wearable)
implementation(platform(libs.androidx.compose))
implementation(libs.androidx.paging.compose) implementation(libs.androidx.paging.compose)
implementation(libs.androidx.ui) implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics) implementation(libs.androidx.ui.graphics)

@ -62,6 +62,7 @@ class MainActivity : ComponentActivity() {
uiItems = taskListItems, uiItems = taskListItems,
onComplete = { taskListViewModel.completeTask(it) }, onComplete = { taskListViewModel.completeTask(it) },
onClick = { navController.navigate("task_edit/$it") }, onClick = { navController.navigate("task_edit/$it") },
addTask = {},
) )
} }
composable( composable(

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.CheckBox import androidx.compose.material.icons.outlined.CheckBox
import androidx.compose.material.icons.outlined.CheckBoxOutlineBlank import androidx.compose.material.icons.outlined.CheckBoxOutlineBlank
import androidx.compose.material.icons.outlined.Repeat import androidx.compose.material.icons.outlined.Repeat
@ -15,6 +16,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.LazyPagingItems
import androidx.wear.compose.material.Button import androidx.wear.compose.material.Button
@ -28,8 +30,11 @@ import com.google.android.horologist.compose.layout.ScalingLazyColumn
import com.google.android.horologist.compose.layout.ScreenScaffold import com.google.android.horologist.compose.layout.ScreenScaffold
import com.google.android.horologist.compose.layout.rememberResponsiveColumnState import com.google.android.horologist.compose.layout.rememberResponsiveColumnState
import com.google.android.horologist.compose.paging.items import com.google.android.horologist.compose.paging.items
import org.jetbrains.compose.resources.stringResource
import org.tasks.GrpcProto import org.tasks.GrpcProto
import org.tasks.kmp.org.tasks.themes.ColorProvider import org.tasks.kmp.org.tasks.themes.ColorProvider
import tasks.kmp.generated.resources.Res
import tasks.kmp.generated.resources.add_task
@OptIn(ExperimentalHorologistApi::class) @OptIn(ExperimentalHorologistApi::class)
@Composable @Composable
@ -37,6 +42,7 @@ fun TaskListScreen(
uiItems: LazyPagingItems<GrpcProto.UiItem>, uiItems: LazyPagingItems<GrpcProto.UiItem>,
onComplete: (Long) -> Unit, onComplete: (Long) -> Unit,
onClick: (Long) -> Unit, onClick: (Long) -> Unit,
addTask: () -> Unit,
) { ) {
val columnState = rememberResponsiveColumnState() val columnState = rememberResponsiveColumnState()
ScreenScaffold( ScreenScaffold(
@ -46,24 +52,59 @@ fun TaskListScreen(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
columnState = columnState, columnState = columnState,
) { ) {
item {
TaskCard(
text = stringResource(Res.string.add_task),
icon = {
Icon(
imageVector = Icons.Outlined.Add,
tint = MaterialTheme.colors.onPrimary,
contentDescription = null,
modifier = Modifier.padding(12.dp),
)
},
backgroundColor = MaterialTheme.colors.primary,
contentColor = MaterialTheme.colors.onPrimary,
onClick = addTask,
)
}
items( items(
items = uiItems, items = uiItems,
key = { item -> "${item.type}_${item.id}" }, key = { item -> "${item.type}_${item.id}" },
) { item -> ) { item ->
if (item == null) { if (item == null) {
TaskCard( TaskCard(
task = GrpcProto.UiItem.getDefaultInstance(), text = "",
showCheckbox = false, icon = {},
onComplete = {},
onClick = {}, onClick = {},
) )
} else { } else {
when (item.type) { when (item.type) {
GrpcProto.UiItemType.Task -> GrpcProto.UiItemType.Task ->
TaskCard( TaskCard(
task = item, text = item.title,
showCheckbox = true, icon = {
onComplete = { onComplete(item.id) }, Button(
onClick = { onComplete(item.id) },
colors = ButtonDefaults.iconButtonColors(),
) {
Icon(
imageVector = when {
item.completed -> Icons.Outlined.CheckBox
item.repeating -> Icons.Outlined.Repeat
else -> Icons.Outlined.CheckBoxOutlineBlank
},
tint = Color(
ColorProvider.priorityColor(
item.priority,
isDarkMode = true,
desaturate = true
)
),
contentDescription = null,
)
}
},
onClick = { onClick(item.id) }, onClick = { onClick(item.id) },
) )
@ -95,44 +136,26 @@ fun GroupSeparator(
@Composable @Composable
fun TaskCard( fun TaskCard(
task: GrpcProto.UiItem, text: String,
showCheckbox: Boolean, icon: @Composable () -> Unit = {},
onComplete: () -> Unit, backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = MaterialTheme.colors.onSurface,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
Card( Card(
onClick = onClick, onClick = onClick,
backgroundPainter = ColorPainter(MaterialTheme.colors.surface), backgroundPainter = ColorPainter(backgroundColor),
contentPadding = PaddingValues(start = 0.dp, top = 0.dp, end = 12.dp, bottom = 0.dp), contentPadding = PaddingValues(start = 0.dp, top = 0.dp, end = 12.dp, bottom = 0.dp),
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
if (showCheckbox) { icon()
Button(
onClick = onComplete,
colors = ButtonDefaults.iconButtonColors(),
) {
Icon(
imageVector = when {
task.completed -> Icons.Outlined.CheckBox
task.repeating -> Icons.Outlined.Repeat
else -> Icons.Outlined.CheckBoxOutlineBlank
},
tint = Color(
ColorProvider.priorityColor(
task.priority,
isDarkMode = true,
desaturate = true
)
),
contentDescription = null,
)
}
}
Text( Text(
text = task.title, text = text,
modifier = Modifier.padding(vertical = 12.dp) maxLines = 2,
overflow = TextOverflow.Ellipsis,
color = contentColor,
) )
} }
} }

@ -1,17 +1,19 @@
package org.tasks.presentation.theme package org.tasks.presentation.theme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.wear.compose.material.MaterialTheme import androidx.wear.compose.material.MaterialTheme
import org.tasks.kmp.org.tasks.themes.ColorProvider
@Composable @Composable
fun TasksTheme( fun TasksTheme(
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
/**
* Empty theme to customize for your app.
* See: https://developer.android.com/jetpack/compose/designsystems/custom
*/
MaterialTheme( MaterialTheme(
colors = MaterialTheme.colors.copy(
primary = Color(ColorProvider.BLUE_500),
onPrimary = Color.White,
),
content = content content = content
) )
} }
Loading…
Cancel
Save