diff --git a/wear/src/main/java/com/example/util/simpletimetracker/presentation/ActivityChip.kt b/wear/src/main/java/com/example/util/simpletimetracker/presentation/ActivityChip.kt index 139be4bc..e3ac39d4 100644 --- a/wear/src/main/java/com/example/util/simpletimetracker/presentation/ActivityChip.kt +++ b/wear/src/main/java/com/example/util/simpletimetracker/presentation/ActivityChip.kt @@ -5,18 +5,23 @@ */ package com.example.util.simpletimetracker.presentation -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding 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.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.wear.compose.material.Chip -import androidx.wear.compose.material.ChipDefaults +import androidx.wear.compose.material.Switch import androidx.wear.compose.material.Text +import androidx.wear.compose.material.ToggleChip +import androidx.wear.compose.material.ToggleChipDefaults import com.example.util.simpletimetracker.presentation.theme.hexCodeToColor import com.example.util.simpletimetracker.wearrpc.Activity import com.example.util.simpletimetracker.wearrpc.Tag @@ -30,7 +35,7 @@ fun ActivityChip( activity: Activity, startedAt: Long? = null, tags: Array = arrayOf(), - onClick: () -> Unit = {}, + onClick: (Boolean) -> Unit = {}, ) { val briefIcon = if (activity.icon.startsWith("ic_")) { "?" @@ -51,7 +56,8 @@ fun ActivityChip( var modifier = Modifier .fillMaxWidth(0.9f) .padding(top = 10.dp) - Chip( + var switchChecked by remember { mutableStateOf(startedAt != null) } + ToggleChip( modifier = modifier, label = { Text( @@ -60,13 +66,6 @@ fun ActivityChip( overflow = TextOverflow.Ellipsis, ) }, - border = ChipDefaults.chipBorder( - borderStroke = if (startedAt != null) { - BorderStroke(2.dp, Color.White) - } else { - null - }, - ), secondaryLabel = { if (startedAt != null) { Text("Since ${recentTimestampToString(startedAt)}") @@ -74,10 +73,26 @@ fun ActivityChip( null } }, - colors = ChipDefaults.chipColors( - backgroundColor = color, + colors = ToggleChipDefaults.toggleChipColors( + checkedStartBackgroundColor = color, + checkedEndBackgroundColor = color, + uncheckedToggleControlColor = ToggleChipDefaults.SwitchUncheckedIconColor, ), - onClick = onClick, + onCheckedChange = { + switchChecked = it + onClick(switchChecked) + }, + checked = switchChecked, + toggleControl = { + Switch( + checked = switchChecked, + enabled = true, + modifier = Modifier.semantics { + this.contentDescription = + if (switchChecked) "On" else "Off" + }, + ) + }, ) } diff --git a/wear/src/main/java/com/example/util/simpletimetracker/presentation/MainActivity.kt b/wear/src/main/java/com/example/util/simpletimetracker/presentation/MainActivity.kt index 5a8add39..4cf34277 100644 --- a/wear/src/main/java/com/example/util/simpletimetracker/presentation/MainActivity.kt +++ b/wear/src/main/java/com/example/util/simpletimetracker/presentation/MainActivity.kt @@ -27,4 +27,3 @@ fun WearApp() { MainNavigator() } } - diff --git a/wear/src/main/java/com/example/util/simpletimetracker/presentation/components/ActivitiesList.kt b/wear/src/main/java/com/example/util/simpletimetracker/presentation/components/ActivitiesList.kt index 888b286d..54cfa0d4 100644 --- a/wear/src/main/java/com/example/util/simpletimetracker/presentation/components/ActivitiesList.kt +++ b/wear/src/main/java/com/example/util/simpletimetracker/presentation/components/ActivitiesList.kt @@ -19,6 +19,7 @@ fun ActivitiesList( activities: Array, currentActivities: Array, onSelectActivity: (activity: Activity) -> Unit, + onDeselectActivity: (activity: Activity) -> Unit, onRefresh: () -> Unit, ) { ScaffoldedScrollingColumn { @@ -29,7 +30,7 @@ fun ActivitiesList( activity, startedAt = currentActivity?.startedAt, tags = currentActivity?.tags ?: arrayOf(), - onClick = { onSelectActivity(activity) }, + onClick = { if (it) onSelectActivity(activity) else onDeselectActivity(activity) }, ) } } @@ -56,6 +57,7 @@ private fun Preview() { activities, currentActivities = currents, onSelectActivity = { /* `it` is the selected activity */ }, + onDeselectActivity = { /* `it` is the deselected activity */ }, onRefresh = { /* What to do when requesting a refresh */ } ) } \ No newline at end of file diff --git a/wear/src/main/java/com/example/util/simpletimetracker/presentation/remember/currentActivities.kt b/wear/src/main/java/com/example/util/simpletimetracker/presentation/remember/currentActivities.kt index d0aafbdf..4654990f 100644 --- a/wear/src/main/java/com/example/util/simpletimetracker/presentation/remember/currentActivities.kt +++ b/wear/src/main/java/com/example/util/simpletimetracker/presentation/remember/currentActivities.kt @@ -11,11 +11,13 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import com.example.util.simpletimetracker.wearrpc.CurrentActivity import com.example.util.simpletimetracker.wearrpc.WearRPCClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async +import kotlinx.coroutines.launch /** * Handles asynchronous retrieval of the currently running activities in Simple Time Tracker on the @@ -35,13 +37,31 @@ import kotlinx.coroutines.async * from the phone. */ @Composable -fun rememberCurrentActivities(rpc: WearRPCClient): Pair, () -> Unit> { +fun rememberCurrentActivities( + rpc: WearRPCClient, +): Triple< + Array, + ((Array) -> (Array)) -> Unit, + () -> Unit, + > { var currentActivities: Array by remember { mutableStateOf(arrayOf()) } var currentActivitiesQueryCount by remember { mutableIntStateOf(0) } + val queryCurrentActivities = { currentActivitiesQueryCount++ } + val coroutineScope = rememberCoroutineScope() LaunchedEffect(currentActivitiesQueryCount) { async(Dispatchers.Default) { currentActivities = rpc.queryCurrentActivities() } } - return Pair(currentActivities) { currentActivitiesQueryCount++ } + + return Triple( + currentActivities, + { affectCurrentActivities -> + currentActivities = affectCurrentActivities(currentActivities) + coroutineScope.launch(Dispatchers.Default) { + rpc.setCurrentActivities(currentActivities) + queryCurrentActivities() + } + }, { queryCurrentActivities() }, + ) } \ No newline at end of file diff --git a/wear/src/main/java/com/example/util/simpletimetracker/presentation/screens/ActivitiesScreen.kt b/wear/src/main/java/com/example/util/simpletimetracker/presentation/screens/ActivitiesScreen.kt index 430a2dbe..33be4f2f 100644 --- a/wear/src/main/java/com/example/util/simpletimetracker/presentation/screens/ActivitiesScreen.kt +++ b/wear/src/main/java/com/example/util/simpletimetracker/presentation/screens/ActivitiesScreen.kt @@ -10,15 +10,16 @@ import androidx.compose.ui.platform.LocalContext import com.example.util.simpletimetracker.presentation.components.ActivitiesList import com.example.util.simpletimetracker.presentation.remember.rememberActivities import com.example.util.simpletimetracker.presentation.remember.rememberCurrentActivities +import com.example.util.simpletimetracker.wearrpc.Activity import com.example.util.simpletimetracker.wearrpc.ContextMessenger import com.example.util.simpletimetracker.wearrpc.WearRPCClient - @Composable fun ActivitiesScreen(onSelectActivity: (activityId: Long) -> Unit) { val rpc = WearRPCClient(ContextMessenger(LocalContext.current)) val (activities, refreshActivities) = rememberActivities(rpc) - val (currentActivities, refreshCurrentActivities) = rememberCurrentActivities(rpc) + val (currentActivities, affectCurrentActivities, refreshCurrentActivities) = + rememberCurrentActivities(rpc) ActivitiesList( activities, @@ -26,12 +27,14 @@ fun ActivitiesScreen(onSelectActivity: (activityId: Long) -> Unit) { onSelectActivity = { onSelectActivity(it.id) }, + onDeselectActivity = { deselectedActivity: Activity -> + affectCurrentActivities { + currentActivities.filter { it.id != deselectedActivity.id }.toTypedArray() + } + }, onRefresh = { refreshActivities() refreshCurrentActivities() }, ) } - - -