Skip to content

Commit

Permalink
Add helpers for duplicate Wear Compose code (#2175)
Browse files Browse the repository at this point in the history
* Add ExpandableListHeader, rememberExpandedStates

* Add helper for ScalingLazyColumn

* Add helper for Chip in Settings

* Swap if statement
  • Loading branch information
NotWoods authored Jan 22, 2022
1 parent bee5116 commit 6bc0512
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 311 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package io.homeassistant.companion.android.home.views

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
Expand All @@ -20,18 +14,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.ScalingLazyColumn
import androidx.wear.compose.material.ScalingLazyListState
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.rememberScalingLazyListState
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.common.data.integration.Entity
import io.homeassistant.companion.android.data.SimplifiedEntity
import io.homeassistant.companion.android.home.MainViewModel
import io.homeassistant.companion.android.theme.WearAppTheme
import io.homeassistant.companion.android.util.getIcon
import io.homeassistant.companion.android.util.scrollHandler
import io.homeassistant.companion.android.common.R as commonR

@ExperimentalComposeUiApi
Expand All @@ -42,32 +32,12 @@ fun ChooseEntityView(
onEntitySelected: (entity: SimplifiedEntity) -> Unit
) {
// Remember expanded state of each header
val expandedStates = remember {
mutableStateMapOf<String, Boolean>().apply {
mainViewModel.supportedDomains().forEach {
put(it, true)
}
}
}
val expandedStates = rememberExpandedStates(mainViewModel.supportedDomains())

val scalingLazyListState: ScalingLazyListState = rememberScalingLazyListState()
LocalView.current.requestFocus()

WearAppTheme {
ScalingLazyColumn(
modifier = Modifier
.fillMaxSize()
.scrollHandler(scalingLazyListState),
contentPadding = PaddingValues(
top = 24.dp,
start = 8.dp,
end = 8.dp,
bottom = 48.dp
),
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalAlignment = Alignment.CenterHorizontally,
state = scalingLazyListState
) {
ThemeLazyColumn {
item {
ListHeader(id = commonR.string.shortcuts_choose)
}
Expand All @@ -85,19 +55,19 @@ fun ChooseEntityView(
)
}
for (domain in mainViewModel.entitiesByDomainOrder) {
val entities = mainViewModel.entitiesByDomain[domain].orEmpty()
if (entities.isNotEmpty()) {
val entities = mainViewModel.entitiesByDomain[domain]
if (!entities.isNullOrEmpty()) {
item {
ListHeader(
ExpandableListHeader(
string = mainViewModel.stringForDomain(domain)!!,
expanded = expandedStates[domain]!!,
onExpandChanged = { expandedStates[domain] = it }
key = domain,
expandedStates = expandedStates
)
}
if (expandedStates[domain] == true) {
items(mainViewModel.entitiesByDomain[domain].orEmpty().size) { index ->
items(entities.size) { index ->
ChooseEntityChip(
entityList = mainViewModel.entitiesByDomain[domain]!!,
entityList = entities,
index = index,
onEntitySelected = onEntitySelected
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
package io.homeassistant.companion.android.home.views

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
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.ExperimentalWearMaterialApi
import androidx.wear.compose.material.ScalingLazyColumn
import androidx.wear.compose.material.ScalingLazyListState
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.rememberScalingLazyListState
import io.homeassistant.companion.android.common.data.integration.Entity
import io.homeassistant.companion.android.theme.WearAppTheme
import io.homeassistant.companion.android.util.previewEntity1
import io.homeassistant.companion.android.util.previewEntity2
import io.homeassistant.companion.android.util.scrollHandler
import io.homeassistant.companion.android.common.R as commonR

@ExperimentalComposeUiApi
Expand All @@ -40,41 +28,21 @@ fun EntityViewList(
isToastEnabled: Boolean
) {
// Remember expanded state of each header
val expandedStates = remember {
mutableStateMapOf<Int, Boolean>().apply {
entityLists.forEach {
put(it.key.hashCode(), true)
}
}
}
val expandedStates = rememberExpandedStates(entityLists.keys.map { it.hashCode() })

val scalingLazyListState: ScalingLazyListState = rememberScalingLazyListState()
LocalView.current.requestFocus()

WearAppTheme {
ScalingLazyColumn(
modifier = Modifier
.fillMaxSize()
.scrollHandler(scalingLazyListState),
contentPadding = PaddingValues(
top = 24.dp,
start = 8.dp,
end = 8.dp,
bottom = 48.dp
),
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalAlignment = Alignment.CenterHorizontally,
state = scalingLazyListState
) {
ThemeLazyColumn {
for (header in entityListsOrder) {
val entities = entityLists[header].orEmpty()
if (entities.isNotEmpty()) {
item {
if (entityLists.size > 1) {
ListHeader(
ExpandableListHeader(
string = header,
expanded = expandedStates[header.hashCode()]!!,
onExpandChanged = { expandedStates[header.hashCode()] = it }
key = header.hashCode(),
expandedStates = expandedStates
)
} else {
ListHeader(header)
Expand All @@ -91,7 +59,7 @@ fun EntityViewList(
)
}

if (filtered.isNullOrEmpty()) {
if (filtered.isEmpty()) {
item {
Column {
Chip(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package io.homeassistant.companion.android.home.views

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.wear.compose.material.Text
import io.homeassistant.companion.android.common.R
import org.checkerframework.checker.units.qual.K

/**
* Remember expanded state of each header
*/
@Composable
fun <K> rememberExpandedStates(
initialKeys: Iterable<K>
): SnapshotStateMap<K, Boolean> {
return remember {
mutableStateMapOf<K, Boolean>().apply {
initialKeys.forEach { key ->
put(key, true)
}
}
}
}

@Composable
fun ExpandableListHeader(
string: String,
expanded: Boolean,
onExpandChanged: (Boolean) -> Unit
) {
androidx.wear.compose.material.ListHeader(
modifier = Modifier
.clickable { onExpandChanged(!expanded) }
) {
Row {
val plusMinus = if (expanded) "-" else "+"
Text(
text = "$string\u2001$plusMinus"
)
}
}
}

@Composable
fun <K> ExpandableListHeader(
string: String,
key: K,
expandedStates: SnapshotStateMap<K, Boolean>
) {
ExpandableListHeader(
string = string,
expanded = expandedStates.getOrDefault(key, true),
onExpandChanged = { expandedStates[key] = it }
)
}

@Preview
@Composable
private fun PreviewExpandableListHeader() {
ExpandableListHeader(
string = stringResource(R.string.other),
expanded = true,
onExpandChanged = {}
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.homeassistant.companion.android.home.views

import androidx.compose.foundation.clickable
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
Expand All @@ -11,34 +11,7 @@ import androidx.wear.compose.material.Text
import io.homeassistant.companion.android.common.R as commonR

@Composable
fun ListHeader(
stringId: Int,
expanded: Boolean,
onExpandChanged: (Boolean) -> Unit
) {
ListHeader(stringResource(stringId), expanded, onExpandChanged)
}

@Composable
fun ListHeader(
string: String,
expanded: Boolean,
onExpandChanged: (Boolean) -> Unit
) {
ListHeader(
modifier = Modifier
.clickable { onExpandChanged(!expanded) }
) {
Row {
Text(
text = string + if (expanded) "\u2001-" else "\u2001+"
)
}
}
}

@Composable
fun ListHeader(id: Int, modifier: Modifier = Modifier) {
fun ListHeader(@StringRes id: Int, modifier: Modifier = Modifier) {
ListHeader(stringResource(id), modifier)
}

Expand All @@ -58,8 +31,6 @@ fun ListHeader(string: String, modifier: Modifier = Modifier) {
@Composable
private fun PreviewListHeader() {
ListHeader(
stringId = commonR.string.other,
expanded = true,
onExpandChanged = {}
id = commonR.string.other
)
}
Loading

0 comments on commit 6bc0512

Please sign in to comment.