mirror of
https://github.com/home-assistant/android
synced 2024-10-01 13:53:53 +00:00
Add missing scroll bar to remaining screens (#3895)
* Add missing scroll bar to remaining screens * Add Scaffold to ThemeLazyColumn * Remove unneeded variable * Remove nested scaffold
This commit is contained in:
parent
2f777a1379
commit
a15f7b3bc4
|
@ -43,8 +43,6 @@ import androidx.wear.compose.material.ButtonDefaults
|
|||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.LocalContentColor
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.navigation.SwipeDismissableNavHost
|
||||
import androidx.wear.compose.navigation.composable
|
||||
|
@ -55,7 +53,6 @@ import io.homeassistant.companion.android.common.R
|
|||
import io.homeassistant.companion.android.common.assist.AssistViewModelBase
|
||||
import io.homeassistant.companion.android.common.data.websocket.impl.entities.AssistPipelineResponse
|
||||
import io.homeassistant.companion.android.conversation.ConversationViewModel
|
||||
import io.homeassistant.companion.android.home.views.TimeText
|
||||
import io.homeassistant.companion.android.theme.WearAppTheme
|
||||
import io.homeassistant.companion.android.util.KeepScreenOn
|
||||
import io.homeassistant.companion.android.views.ListHeader
|
||||
|
@ -117,103 +114,93 @@ fun ConversationResultView(
|
|||
onMicrophoneInput: () -> Unit
|
||||
) {
|
||||
val scrollState = rememberScalingLazyListState()
|
||||
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scrollState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scrollState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scrollState) }
|
||||
) {
|
||||
LaunchedEffect(conversation.size) {
|
||||
scrollState.scrollToItem(
|
||||
if (inputMode != AssistViewModelBase.AssistInputMode.BLOCKED) conversation.size else (conversation.size - 1)
|
||||
)
|
||||
}
|
||||
if (hapticFeedback) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
LaunchedEffect("${conversation.size}.${conversation.lastOrNull()?.message?.length}") {
|
||||
val message = conversation.lastOrNull() ?: return@LaunchedEffect
|
||||
if (conversation.size > 1 && !message.isInput && message.message != "…") {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
}
|
||||
LaunchedEffect(conversation.size) {
|
||||
scrollState.scrollToItem(
|
||||
if (inputMode != AssistViewModelBase.AssistInputMode.BLOCKED) conversation.size else (conversation.size - 1)
|
||||
)
|
||||
}
|
||||
if (hapticFeedback) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
LaunchedEffect("${conversation.size}.${conversation.lastOrNull()?.message?.length}") {
|
||||
val message = conversation.lastOrNull() ?: return@LaunchedEffect
|
||||
if (conversation.size > 1 && !message.isInput && message.message != "…") {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThemeLazyColumn(state = scrollState) {
|
||||
item {
|
||||
if (currentPipeline != null) {
|
||||
val textColor = LocalContentColor.current.copy(alpha = 0.38f) // disabled/hint alpha
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = { onChangePipeline() },
|
||||
onClickLabel = stringResource(R.string.assist_change_pipeline)
|
||||
)
|
||||
.padding(bottom = 4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = currentPipeline.name,
|
||||
fontSize = 11.sp,
|
||||
color = textColor
|
||||
ThemeLazyColumn(state = scrollState) {
|
||||
item {
|
||||
if (currentPipeline != null) {
|
||||
val textColor = LocalContentColor.current.copy(alpha = 0.38f) // disabled/hint alpha
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = { onChangePipeline() },
|
||||
onClickLabel = stringResource(R.string.assist_change_pipeline)
|
||||
)
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_chevron_right,
|
||||
.padding(bottom = 4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = currentPipeline.name,
|
||||
fontSize = 11.sp,
|
||||
color = textColor
|
||||
)
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_chevron_right,
|
||||
modifier = Modifier
|
||||
.size(16.dp)
|
||||
.padding(start = 4.dp),
|
||||
colorFilter = ColorFilter.tint(textColor)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
}
|
||||
items(conversation) {
|
||||
SpeechBubble(text = it.message, isResponse = !it.isInput)
|
||||
}
|
||||
if (inputMode != AssistViewModelBase.AssistInputMode.BLOCKED) {
|
||||
item {
|
||||
Box(
|
||||
modifier = Modifier.size(64.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
val inputIsActive = inputMode == AssistViewModelBase.AssistInputMode.VOICE_ACTIVE
|
||||
if (inputIsActive) {
|
||||
KeepScreenOn()
|
||||
val transition = rememberInfiniteTransition()
|
||||
val scale by transition.animateFloat(
|
||||
initialValue = 1f,
|
||||
targetValue = 1.2f,
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = tween(600, easing = LinearEasing),
|
||||
repeatMode = RepeatMode.Reverse
|
||||
)
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(16.dp)
|
||||
.padding(start = 4.dp),
|
||||
colorFilter = ColorFilter.tint(textColor)
|
||||
.size(48.dp)
|
||||
.scale(scale)
|
||||
.background(color = colorResource(R.color.colorSpeechText), shape = CircleShape)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
}
|
||||
items(conversation) {
|
||||
SpeechBubble(text = it.message, isResponse = !it.isInput)
|
||||
}
|
||||
if (inputMode != AssistViewModelBase.AssistInputMode.BLOCKED) {
|
||||
item {
|
||||
Box(
|
||||
modifier = Modifier.size(64.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
val inputIsActive = inputMode == AssistViewModelBase.AssistInputMode.VOICE_ACTIVE
|
||||
Button(
|
||||
onClick = { onMicrophoneInput() },
|
||||
colors =
|
||||
if (inputIsActive) {
|
||||
KeepScreenOn()
|
||||
val transition = rememberInfiniteTransition()
|
||||
val scale by transition.animateFloat(
|
||||
initialValue = 1f,
|
||||
targetValue = 1.2f,
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = tween(600, easing = LinearEasing),
|
||||
repeatMode = RepeatMode.Reverse
|
||||
)
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.scale(scale)
|
||||
.background(color = colorResource(R.color.colorSpeechText), shape = CircleShape)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
}
|
||||
Button(
|
||||
onClick = { onMicrophoneInput() },
|
||||
colors =
|
||||
if (inputIsActive) {
|
||||
ButtonDefaults.secondaryButtonColors(backgroundColor = Color.Transparent, contentColor = Color.Black)
|
||||
} else {
|
||||
ButtonDefaults.secondaryButtonColors()
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon3.cmd_microphone,
|
||||
contentDescription = stringResource(R.string.assist_start_listening),
|
||||
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
||||
)
|
||||
ButtonDefaults.secondaryButtonColors(backgroundColor = Color.Transparent, contentColor = Color.Black)
|
||||
} else {
|
||||
ButtonDefaults.secondaryButtonColors()
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon3.cmd_microphone,
|
||||
contentDescription = stringResource(R.string.assist_start_listening),
|
||||
colorFilter = ColorFilter.tint(LocalContentColor.current)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,9 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Icon
|
||||
import androidx.wear.compose.material.InlineSlider
|
||||
import androidx.wear.compose.material.InlineSliderDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material.ToggleButton
|
||||
import androidx.wear.compose.material.ToggleButtonDefaults
|
||||
|
@ -62,116 +59,106 @@ fun DetailsPanelView(
|
|||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val context = LocalContext.current
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
val attributes = entity.attributes as Map<*, *>
|
||||
ThemeLazyColumn {
|
||||
val attributes = entity.attributes as Map<*, *>
|
||||
|
||||
item {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val friendlyName = attributes["friendly_name"].toString()
|
||||
Text(friendlyName)
|
||||
item {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val friendlyName = attributes["friendly_name"].toString()
|
||||
Text(friendlyName)
|
||||
|
||||
if (entity.domain in EntityExt.DOMAINS_TOGGLE) {
|
||||
val isChecked = entity.state in listOf("on", "locked", "open", "opening")
|
||||
ToggleButton(
|
||||
checked = isChecked,
|
||||
onCheckedChange = {
|
||||
onEntityToggled(entity.entityId, entity.state)
|
||||
onEntityClickedFeedback(
|
||||
isToastEnabled,
|
||||
isHapticEnabled,
|
||||
context,
|
||||
friendlyName,
|
||||
haptic
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp)
|
||||
.size(ToggleButtonDefaults.SmallToggleButtonSize)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.switchIcon(isChecked),
|
||||
contentDescription = if (isChecked) {
|
||||
stringResource(R.string.enabled)
|
||||
} else {
|
||||
stringResource(R.string.disabled)
|
||||
}
|
||||
if (entity.domain in EntityExt.DOMAINS_TOGGLE) {
|
||||
val isChecked = entity.state in listOf("on", "locked", "open", "opening")
|
||||
ToggleButton(
|
||||
checked = isChecked,
|
||||
onCheckedChange = {
|
||||
onEntityToggled(entity.entityId, entity.state)
|
||||
onEntityClickedFeedback(
|
||||
isToastEnabled,
|
||||
isHapticEnabled,
|
||||
context,
|
||||
friendlyName,
|
||||
haptic
|
||||
)
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp)
|
||||
.size(ToggleButtonDefaults.SmallToggleButtonSize)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.switchIcon(isChecked),
|
||||
contentDescription = if (isChecked) {
|
||||
stringResource(R.string.enabled)
|
||||
} else {
|
||||
stringResource(R.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.domain == "fan") {
|
||||
if (entity.supportsFanSetSpeed()) {
|
||||
item {
|
||||
FanSpeedSlider(entity, onFanSpeedChanged, isToastEnabled, isHapticEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entity.domain == "light") {
|
||||
if (entity.supportsLightBrightness()) {
|
||||
item {
|
||||
BrightnessSlider(entity, onBrightnessChanged, isToastEnabled, isHapticEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.domain == "fan") {
|
||||
if (entity.supportsFanSetSpeed()) {
|
||||
item {
|
||||
FanSpeedSlider(entity, onFanSpeedChanged, isToastEnabled, isHapticEnabled)
|
||||
}
|
||||
if (entity.supportsLightColorTemperature() && attributes["color_mode"] == EntityExt.LIGHT_MODE_COLOR_TEMP) {
|
||||
item {
|
||||
ColorTempSlider(attributes, onColorTempChanged, isToastEnabled, isHapticEnabled)
|
||||
}
|
||||
}
|
||||
if (entity.domain == "light") {
|
||||
if (entity.supportsLightBrightness()) {
|
||||
item {
|
||||
BrightnessSlider(entity, onBrightnessChanged, isToastEnabled, isHapticEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.supportsLightColorTemperature() && attributes["color_mode"] == EntityExt.LIGHT_MODE_COLOR_TEMP) {
|
||||
item {
|
||||
ColorTempSlider(attributes, onColorTempChanged, isToastEnabled, isHapticEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
ListHeader(R.string.details)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
stringResource(R.string.state_name, entity.state),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
val lastChanged = DateFormat.getDateTimeInstance().format(entity.lastChanged.time)
|
||||
Text(
|
||||
stringResource(R.string.last_changed, lastChanged),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
val lastUpdated = DateFormat.getDateTimeInstance().format(entity.lastUpdated.time)
|
||||
Text(
|
||||
stringResource(R.string.last_updated, lastUpdated),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
stringResource(R.string.entity_id_name, entity.entityId),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(R.string.details)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
stringResource(R.string.state_name, entity.state),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
val lastChanged = DateFormat.getDateTimeInstance().format(entity.lastChanged.time)
|
||||
Text(
|
||||
stringResource(R.string.last_changed, lastChanged),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
val lastUpdated = DateFormat.getDateTimeInstance().format(entity.lastUpdated.time)
|
||||
Text(
|
||||
stringResource(R.string.last_updated, lastUpdated),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
stringResource(R.string.entity_id_name, entity.entityId),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.wear.compose.foundation.lazy.items
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import io.homeassistant.companion.android.common.data.integration.Entity
|
||||
import io.homeassistant.companion.android.theme.WearAppTheme
|
||||
|
@ -38,57 +35,47 @@ fun EntityViewList(
|
|||
) {
|
||||
// Remember expanded state of each header
|
||||
val expandedStates = rememberExpandedStates(entityLists.keys.map { it.hashCode() })
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
for (header in entityListsOrder) {
|
||||
val entities = entityLists[header].orEmpty()
|
||||
if (entities.isNotEmpty()) {
|
||||
item {
|
||||
if (entityLists.size > 1) {
|
||||
ExpandableListHeader(
|
||||
string = header,
|
||||
key = header.hashCode(),
|
||||
expandedStates = expandedStates
|
||||
)
|
||||
} else {
|
||||
ListHeader(header)
|
||||
}
|
||||
ThemeLazyColumn {
|
||||
for (header in entityListsOrder) {
|
||||
val entities = entityLists[header].orEmpty()
|
||||
if (entities.isNotEmpty()) {
|
||||
item {
|
||||
if (entityLists.size > 1) {
|
||||
ExpandableListHeader(
|
||||
string = header,
|
||||
key = header.hashCode(),
|
||||
expandedStates = expandedStates
|
||||
)
|
||||
} else {
|
||||
ListHeader(header)
|
||||
}
|
||||
}
|
||||
if (expandedStates[header.hashCode()]!!) {
|
||||
val filtered = entities.filter { entityListFilter(it) }
|
||||
items(filtered, key = { it.entityId }) { entity ->
|
||||
EntityUi(
|
||||
entity,
|
||||
onEntityClicked,
|
||||
isHapticEnabled,
|
||||
isToastEnabled
|
||||
) { entityId -> onEntityLongClicked(entityId) }
|
||||
}
|
||||
if (expandedStates[header.hashCode()]!!) {
|
||||
val filtered = entities.filter { entityListFilter(it) }
|
||||
items(filtered, key = { it.entityId }) { entity ->
|
||||
EntityUi(
|
||||
entity,
|
||||
onEntityClicked,
|
||||
isHapticEnabled,
|
||||
isToastEnabled
|
||||
) { entityId -> onEntityLongClicked(entityId) }
|
||||
}
|
||||
|
||||
if (filtered.isEmpty()) {
|
||||
item {
|
||||
Column {
|
||||
Chip(
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(commonR.string.loading_entities),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
},
|
||||
onClick = { /* No op */ },
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
)
|
||||
}
|
||||
if (filtered.isEmpty()) {
|
||||
item {
|
||||
Column {
|
||||
Chip(
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(commonR.string.loading_entities),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
},
|
||||
onClick = { /* No op */ },
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,10 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.CircularProgressIndicator
|
||||
import androidx.wear.compose.material.MaterialTheme
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import com.mikepenz.iconics.compose.Image
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
|
@ -58,308 +55,295 @@ fun MainView(
|
|||
isHapticEnabled: Boolean,
|
||||
isToastEnabled: Boolean
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
|
||||
var expandedFavorites: Boolean by rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val context = LocalContext.current
|
||||
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
ThemeLazyColumn {
|
||||
if (favoriteEntityIds.isNotEmpty()) {
|
||||
item {
|
||||
ExpandableListHeader(
|
||||
string = stringResource(commonR.string.favorites),
|
||||
expanded = expandedFavorites,
|
||||
onExpandChanged = { expandedFavorites = it }
|
||||
)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(
|
||||
state = scalingLazyListState
|
||||
) {
|
||||
if (favoriteEntityIds.isNotEmpty()) {
|
||||
item {
|
||||
ExpandableListHeader(
|
||||
string = stringResource(commonR.string.favorites),
|
||||
expanded = expandedFavorites,
|
||||
onExpandChanged = { expandedFavorites = it }
|
||||
)
|
||||
if (expandedFavorites) {
|
||||
items(favoriteEntityIds.size) { index ->
|
||||
val favoriteEntityID = favoriteEntityIds[index].split(",")[0]
|
||||
if (mainViewModel.entities.isEmpty()) {
|
||||
// when we don't have the state of the entity, create a Chip from cache as we don't have the state yet
|
||||
val cached = mainViewModel.getCachedEntity(favoriteEntityID)
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = getIcon(cached?.icon, favoriteEntityID.split(".")[0], context),
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = cached?.friendlyName ?: favoriteEntityID,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
onEntityClicked(favoriteEntityID, STATE_UNKNOWN)
|
||||
onEntityClickedFeedback(isToastEnabled, isHapticEnabled, context, favoriteEntityID, haptic)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
} else {
|
||||
mainViewModel.entities.values.toList()
|
||||
.firstOrNull { it.entityId == favoriteEntityID }
|
||||
?.let {
|
||||
EntityUi(
|
||||
mainViewModel.entities[favoriteEntityID]!!,
|
||||
onEntityClicked,
|
||||
isHapticEnabled,
|
||||
isToastEnabled
|
||||
) { entityId -> onEntityLongClicked(entityId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (expandedFavorites) {
|
||||
items(favoriteEntityIds.size) { index ->
|
||||
val favoriteEntityID = favoriteEntityIds[index].split(",")[0]
|
||||
if (mainViewModel.entities.isEmpty()) {
|
||||
// when we don't have the state of the entity, create a Chip from cache as we don't have the state yet
|
||||
val cached = mainViewModel.getCachedEntity(favoriteEntityID)
|
||||
}
|
||||
}
|
||||
|
||||
if (!mainViewModel.isFavoritesOnly) {
|
||||
when (mainViewModel.loadingState.value) {
|
||||
MainViewModel.LoadingState.LOADING -> {
|
||||
if (favoriteEntityIds.isEmpty()) {
|
||||
// Add a Spacer to prevent settings being pushed to the screen center
|
||||
item { Spacer(modifier = Modifier.fillMaxWidth()) }
|
||||
}
|
||||
item {
|
||||
val minHeight =
|
||||
if (favoriteEntityIds.isEmpty()) {
|
||||
LocalConfiguration.current.screenHeightDp - 64
|
||||
} else {
|
||||
0
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.heightIn(min = minHeight.dp)
|
||||
.fillMaxSize()
|
||||
.padding(vertical = if (favoriteEntityIds.isEmpty()) 0.dp else 32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
ListHeader(id = commonR.string.loading)
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
MainViewModel.LoadingState.ERROR -> {
|
||||
item {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
ListHeader(id = commonR.string.error_loading_entities)
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = getIcon(cached?.icon, favoriteEntityID.split(".")[0], context),
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = cached?.friendlyName ?: favoriteEntityID,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
text = stringResource(commonR.string.retry),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
onEntityClicked(favoriteEntityID, STATE_UNKNOWN)
|
||||
onEntityClickedFeedback(isToastEnabled, isHapticEnabled, context, favoriteEntityID, haptic)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
onClick = onRetryLoadEntitiesClicked,
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
)
|
||||
} else {
|
||||
mainViewModel.entities.values.toList()
|
||||
.firstOrNull { it.entityId == favoriteEntityID }
|
||||
?.let {
|
||||
EntityUi(
|
||||
mainViewModel.entities[favoriteEntityID]!!,
|
||||
onEntityClicked,
|
||||
isHapticEnabled,
|
||||
isToastEnabled
|
||||
) { entityId -> onEntityLongClicked(entityId) }
|
||||
}
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mainViewModel.isFavoritesOnly) {
|
||||
when (mainViewModel.loadingState.value) {
|
||||
MainViewModel.LoadingState.LOADING -> {
|
||||
if (favoriteEntityIds.isEmpty()) {
|
||||
// Add a Spacer to prevent settings being pushed to the screen center
|
||||
item { Spacer(modifier = Modifier.fillMaxWidth()) }
|
||||
}
|
||||
item {
|
||||
val minHeight =
|
||||
if (favoriteEntityIds.isEmpty()) {
|
||||
LocalConfiguration.current.screenHeightDp - 64
|
||||
} else {
|
||||
0
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.heightIn(min = minHeight.dp)
|
||||
.fillMaxSize()
|
||||
.padding(vertical = if (favoriteEntityIds.isEmpty()) 0.dp else 32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
ListHeader(id = commonR.string.loading)
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
MainViewModel.LoadingState.ERROR -> {
|
||||
MainViewModel.LoadingState.READY -> {
|
||||
if (mainViewModel.entities.isEmpty()) {
|
||||
item {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
ListHeader(id = commonR.string.error_loading_entities)
|
||||
Chip(
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(commonR.string.retry),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
onClick = onRetryLoadEntitiesClicked,
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
Text(
|
||||
text = stringResource(commonR.string.no_supported_entities),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.title3,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(top = 32.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(commonR.string.no_supported_entities_summary),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.body2,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
MainViewModel.LoadingState.READY -> {
|
||||
if (mainViewModel.entities.isEmpty()) {
|
||||
item {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(commonR.string.no_supported_entities),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.title3,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(top = 32.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(commonR.string.no_supported_entities_summary),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.body2,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
mainViewModel.entitiesByArea.values.any {
|
||||
it.isNotEmpty() && it.any { entity ->
|
||||
mainViewModel.getCategoryForEntity(entity.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(entity.entityId) == null
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
mainViewModel.entitiesByArea.values.any {
|
||||
it.isNotEmpty() && it.any { entity ->
|
||||
mainViewModel.getCategoryForEntity(entity.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(entity.entityId) == null
|
||||
}
|
||||
}
|
||||
) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.areas)
|
||||
}
|
||||
for (id in mainViewModel.entitiesByAreaOrder) {
|
||||
val entities = mainViewModel.entitiesByArea[id]
|
||||
val entitiesToShow = entities?.filter {
|
||||
mainViewModel.getCategoryForEntity(it.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(it.entityId) == null
|
||||
}
|
||||
if (!entitiesToShow.isNullOrEmpty()) {
|
||||
val area = mainViewModel.areas.first { it.areaId == id }
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = {
|
||||
Text(text = area.name)
|
||||
},
|
||||
onClick = {
|
||||
onNavigationClicked(
|
||||
mapOf(area.name to entities),
|
||||
listOf(area.name)
|
||||
) {
|
||||
mainViewModel.getCategoryForEntity(it.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(
|
||||
it.entityId
|
||||
) == null
|
||||
}
|
||||
},
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.areas)
|
||||
}
|
||||
|
||||
val domainEntitiesFilter: (entity: Entity<*>) -> Boolean =
|
||||
{
|
||||
mainViewModel.getAreaForEntity(it.entityId) == null &&
|
||||
mainViewModel.getCategoryForEntity(it.entityId) == null &&
|
||||
for (id in mainViewModel.entitiesByAreaOrder) {
|
||||
val entities = mainViewModel.entitiesByArea[id]
|
||||
val entitiesToShow = entities?.filter {
|
||||
mainViewModel.getCategoryForEntity(it.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(it.entityId) == null
|
||||
}
|
||||
if (mainViewModel.entities.values.any(domainEntitiesFilter)) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.more_entities)
|
||||
}
|
||||
}
|
||||
// Buttons for each existing category
|
||||
for (domain in mainViewModel.entitiesByDomainOrder) {
|
||||
val domainEntities = mainViewModel.entitiesByDomain[domain]!!
|
||||
val domainEntitiesToShow =
|
||||
domainEntities.filter(domainEntitiesFilter)
|
||||
if (domainEntitiesToShow.isNotEmpty()) {
|
||||
if (!entitiesToShow.isNullOrEmpty()) {
|
||||
val area = mainViewModel.areas.first { it.areaId == id }
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
getIcon(
|
||||
"",
|
||||
domain,
|
||||
context
|
||||
).let { Image(asset = it) }
|
||||
},
|
||||
label = {
|
||||
Text(text = mainViewModel.stringForDomain(domain)!!)
|
||||
Text(text = area.name)
|
||||
},
|
||||
onClick = {
|
||||
onNavigationClicked(
|
||||
mapOf(
|
||||
mainViewModel.stringForDomain(domain)!! to domainEntities
|
||||
),
|
||||
listOf(mainViewModel.stringForDomain(domain)!!),
|
||||
domainEntitiesFilter
|
||||
)
|
||||
mapOf(area.name to entities),
|
||||
listOf(area.name)
|
||||
) {
|
||||
mainViewModel.getCategoryForEntity(it.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(
|
||||
it.entityId
|
||||
) == null
|
||||
}
|
||||
},
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
val domainEntitiesFilter: (entity: Entity<*>) -> Boolean =
|
||||
{
|
||||
mainViewModel.getAreaForEntity(it.entityId) == null &&
|
||||
mainViewModel.getCategoryForEntity(it.entityId) == null &&
|
||||
mainViewModel.getHiddenByForEntity(it.entityId) == null
|
||||
}
|
||||
// All entities regardless of area
|
||||
if (mainViewModel.entities.isNotEmpty()) {
|
||||
if (mainViewModel.entities.values.any(domainEntitiesFilter)) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.more_entities)
|
||||
}
|
||||
}
|
||||
// Buttons for each existing category
|
||||
for (domain in mainViewModel.entitiesByDomainOrder) {
|
||||
val domainEntities = mainViewModel.entitiesByDomain[domain]!!
|
||||
val domainEntitiesToShow =
|
||||
domainEntities.filter(domainEntitiesFilter)
|
||||
if (domainEntitiesToShow.isNotEmpty()) {
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_animation,
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
getIcon(
|
||||
"",
|
||||
domain,
|
||||
context
|
||||
).let { Image(asset = it) }
|
||||
},
|
||||
label = {
|
||||
Text(text = stringResource(commonR.string.all_entities))
|
||||
Text(text = mainViewModel.stringForDomain(domain)!!)
|
||||
},
|
||||
onClick = {
|
||||
onNavigationClicked(
|
||||
mainViewModel.entitiesByDomain.mapKeys {
|
||||
mainViewModel.stringForDomain(
|
||||
it.key
|
||||
)!!
|
||||
},
|
||||
mainViewModel.entitiesByDomain.keys.map {
|
||||
mainViewModel.stringForDomain(
|
||||
it
|
||||
)!!
|
||||
}.sorted()
|
||||
) { true }
|
||||
mapOf(
|
||||
mainViewModel.stringForDomain(domain)!! to domainEntities
|
||||
),
|
||||
listOf(mainViewModel.stringForDomain(domain)!!),
|
||||
domainEntitiesFilter
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
colors = ChipDefaults.primaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
// All entities regardless of area
|
||||
if (mainViewModel.entities.isNotEmpty()) {
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_animation,
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(text = stringResource(commonR.string.all_entities))
|
||||
},
|
||||
onClick = {
|
||||
onNavigationClicked(
|
||||
mainViewModel.entitiesByDomain.mapKeys {
|
||||
mainViewModel.stringForDomain(
|
||||
it.key
|
||||
)!!
|
||||
},
|
||||
mainViewModel.entitiesByDomain.keys.map {
|
||||
mainViewModel.stringForDomain(
|
||||
it
|
||||
)!!
|
||||
}.sorted()
|
||||
) { true }
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mainViewModel.isFavoritesOnly) {
|
||||
item {
|
||||
Spacer(Modifier.padding(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
// Settings
|
||||
if (mainViewModel.isFavoritesOnly) {
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_cog,
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = commonR.string.settings)
|
||||
)
|
||||
},
|
||||
onClick = onSettingsClicked,
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
Spacer(Modifier.padding(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
// Settings
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_cog,
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = commonR.string.settings)
|
||||
)
|
||||
},
|
||||
onClick = onSettingsClicked,
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.wear.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import io.homeassistant.companion.android.database.wear.CameraTile
|
||||
import io.homeassistant.companion.android.theme.WearAppTheme
|
||||
|
@ -25,43 +22,33 @@ fun SelectCameraTileView(
|
|||
tiles: List<CameraTile>,
|
||||
onSelectTile: (tileId: Int) -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = commonR.string.camera_tiles)
|
||||
}
|
||||
if (tiles.isEmpty()) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.camera_tiles)
|
||||
Text(
|
||||
text = stringResource(commonR.string.camera_tile_no_tiles_yet),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
if (tiles.isEmpty()) {
|
||||
item {
|
||||
Text(
|
||||
text = stringResource(commonR.string.camera_tile_no_tiles_yet),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
} else {
|
||||
itemsIndexed(tiles, key = { _, item -> "tile.${item.id}" }) { index, tile ->
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = {
|
||||
Text(stringResource(commonR.string.camera_tile_n, index + 1))
|
||||
},
|
||||
secondaryLabel = if (tile.entityId != null) {
|
||||
{ Text(tile.entityId!!) }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
onClick = { onSelectTile(tile.id) },
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
itemsIndexed(tiles, key = { _, item -> "tile.${item.id}" }) { index, tile ->
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = {
|
||||
Text(stringResource(commonR.string.camera_tile_n, index + 1))
|
||||
},
|
||||
secondaryLabel = if (tile.entityId != null) {
|
||||
{ Text(tile.entityId!!) }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
onClick = { onSelectTile(tile.id) },
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,9 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.wear.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.Icon
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material.ToggleChip
|
||||
import androidx.wear.compose.material.ToggleChipDefaults
|
||||
|
@ -33,76 +30,66 @@ fun SelectShortcutsTileView(
|
|||
isShowShortcutTextEnabled: Boolean,
|
||||
onShowShortcutTextEnabled: (Boolean) -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.shortcut_tiles)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isShowShortcutTextEnabled,
|
||||
onCheckedChange = { onShowShortcutTextEnabled(it) },
|
||||
label = {
|
||||
Text(stringResource(commonR.string.shortcuts_tile_text_setting))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset =
|
||||
if (isShowShortcutTextEnabled) {
|
||||
CommunityMaterial.Icon.cmd_alphabetical
|
||||
} else {
|
||||
CommunityMaterial.Icon.cmd_alphabetical_off
|
||||
},
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.checkboxIcon(isShowShortcutTextEnabled),
|
||||
contentDescription = if (isShowShortcutTextEnabled) {
|
||||
stringResource(commonR.string.show)
|
||||
} else {
|
||||
stringResource(commonR.string.hide)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(id = commonR.string.shortcuts_tile_select)
|
||||
}
|
||||
if (shortcutTileEntitiesCountById.isEmpty()) {
|
||||
item {
|
||||
Text(stringResource(commonR.string.shortcuts_tile_no_tiles_yet))
|
||||
}
|
||||
} else {
|
||||
itemsIndexed(shortcutTileEntitiesCountById.keys.toList()) { index, shortcutsTileId ->
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
label = {
|
||||
Text(stringResource(commonR.string.shortcuts_tile_n, index + 1))
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = commonR.string.shortcut_tiles)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isShowShortcutTextEnabled,
|
||||
onCheckedChange = { onShowShortcutTextEnabled(it) },
|
||||
label = {
|
||||
Text(stringResource(commonR.string.shortcuts_tile_text_setting))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset =
|
||||
if (isShowShortcutTextEnabled) {
|
||||
CommunityMaterial.Icon.cmd_alphabetical
|
||||
} else {
|
||||
CommunityMaterial.Icon.cmd_alphabetical_off
|
||||
},
|
||||
secondaryLabel = {
|
||||
val entityCount = shortcutTileEntitiesCountById[shortcutsTileId] ?: 0
|
||||
if (entityCount > 0) {
|
||||
Text(pluralStringResource(commonR.plurals.n_entities, entityCount, entityCount))
|
||||
}
|
||||
},
|
||||
onClick = { onSelectShortcutsTile(shortcutsTileId) },
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.checkboxIcon(isShowShortcutTextEnabled),
|
||||
contentDescription = if (isShowShortcutTextEnabled) {
|
||||
stringResource(commonR.string.show)
|
||||
} else {
|
||||
stringResource(commonR.string.hide)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(id = commonR.string.shortcuts_tile_select)
|
||||
}
|
||||
if (shortcutTileEntitiesCountById.isEmpty()) {
|
||||
item {
|
||||
Text(stringResource(commonR.string.shortcuts_tile_no_tiles_yet))
|
||||
}
|
||||
} else {
|
||||
itemsIndexed(shortcutTileEntitiesCountById.keys.toList()) { index, shortcutsTileId ->
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
label = {
|
||||
Text(stringResource(commonR.string.shortcuts_tile_n, index + 1))
|
||||
},
|
||||
secondaryLabel = {
|
||||
val entityCount = shortcutTileEntitiesCountById[shortcutsTileId] ?: 0
|
||||
if (entityCount > 0) {
|
||||
Text(pluralStringResource(commonR.plurals.n_entities, entityCount, entityCount))
|
||||
}
|
||||
},
|
||||
onClick = { onSelectShortcutsTile(shortcutsTileId) },
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.CircularProgressIndicator
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import io.homeassistant.companion.android.common.R
|
||||
import io.homeassistant.companion.android.common.sensors.SensorManager
|
||||
import io.homeassistant.companion.android.database.sensor.Sensor
|
||||
|
@ -31,54 +28,42 @@ fun SensorManagerUi(
|
|||
sensorManager: SensorManager,
|
||||
onSensorClicked: (String, Boolean) -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(
|
||||
state = scalingLazyListState
|
||||
) {
|
||||
item {
|
||||
ListHeader(id = sensorManager.name)
|
||||
}
|
||||
val currentSensors = allSensors?.filter { sensor ->
|
||||
allAvailSensors?.firstOrNull { availableSensor ->
|
||||
sensor.id == availableSensor.id
|
||||
} != null
|
||||
}
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = sensorManager.name)
|
||||
}
|
||||
val currentSensors = allSensors?.filter { sensor ->
|
||||
allAvailSensors?.firstOrNull { availableSensor ->
|
||||
sensor.id == availableSensor.id
|
||||
} != null
|
||||
}
|
||||
|
||||
if (allAvailSensors?.isEmpty() == true) {
|
||||
item {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(vertical = 32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
ListHeader(id = R.string.loading)
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
if (allAvailSensors?.isEmpty() == true) {
|
||||
item {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(vertical = 32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
ListHeader(id = R.string.loading)
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
allAvailSensors?.size?.let { int ->
|
||||
items(int, { allAvailSensors[it].id }) { index ->
|
||||
val basicSensor = allAvailSensors[index]
|
||||
val sensor = currentSensors?.firstOrNull { sensor ->
|
||||
sensor.id == basicSensor.id
|
||||
}
|
||||
SensorUi(
|
||||
sensor = sensor,
|
||||
manager = sensorManager,
|
||||
basicSensor = basicSensor
|
||||
) { sensorId, enabled -> onSensorClicked(sensorId, enabled) }
|
||||
}
|
||||
} else {
|
||||
allAvailSensors?.size?.let { int ->
|
||||
items(int, { allAvailSensors[it].id }) { index ->
|
||||
val basicSensor = allAvailSensors[index]
|
||||
val sensor = currentSensors?.firstOrNull { sensor ->
|
||||
sensor.id == basicSensor.id
|
||||
}
|
||||
SensorUi(
|
||||
sensor = sensor,
|
||||
manager = sensorManager,
|
||||
basicSensor = basicSensor
|
||||
) { sensorId, enabled -> onSensorClicked(sensorId, enabled) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,8 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import io.homeassistant.companion.android.common.sensors.SensorManager
|
||||
import io.homeassistant.companion.android.sensors.SensorReceiver
|
||||
|
@ -26,39 +23,26 @@ import io.homeassistant.companion.android.common.R as commonR
|
|||
fun SensorsView(
|
||||
onClickSensorManager: (SensorManager) -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
val sensorManagers = getSensorManagers()
|
||||
ThemeLazyColumn(
|
||||
state = scalingLazyListState
|
||||
) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.sensors)
|
||||
}
|
||||
items(sensorManagers.size, { sensorManagers[it].name }) { index ->
|
||||
val manager = sensorManagers[index]
|
||||
Row {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(manager.name)
|
||||
)
|
||||
},
|
||||
onClick = { onClickSensorManager(manager) }
|
||||
)
|
||||
}
|
||||
val sensorManagers = getSensorManagers()
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = commonR.string.sensors)
|
||||
}
|
||||
items(sensorManagers.size, { sensorManagers[it].name }) { index ->
|
||||
val manager = sensorManagers[index]
|
||||
Row {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(manager.name)
|
||||
)
|
||||
},
|
||||
onClick = { onClickSensorManager(manager) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import com.mikepenz.iconics.compose.Image
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
|
@ -34,69 +31,59 @@ fun SetCameraTileView(
|
|||
onSelectEntity: () -> Unit,
|
||||
onSelectRefreshInterval: () -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
item {
|
||||
ListHeader(commonR.string.camera_tile)
|
||||
}
|
||||
item {
|
||||
val entity = tile?.entityId?.let { tileEntityId ->
|
||||
entities?.firstOrNull { it.entityId == tileEntityId }
|
||||
}
|
||||
val icon = entity?.getIcon(LocalContext.current) ?: CommunityMaterial.Icon3.cmd_video
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = icon,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.choose_entity)
|
||||
)
|
||||
},
|
||||
secondaryLabel = {
|
||||
Text(entity?.friendlyName ?: tile?.entityId ?: "")
|
||||
},
|
||||
onClick = onSelectEntity
|
||||
)
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(commonR.string.camera_tile)
|
||||
}
|
||||
item {
|
||||
val entity = tile?.entityId?.let { tileEntityId ->
|
||||
entities?.firstOrNull { it.entityId == tileEntityId }
|
||||
}
|
||||
val icon = entity?.getIcon(LocalContext.current) ?: CommunityMaterial.Icon3.cmd_video
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = icon,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.choose_entity)
|
||||
)
|
||||
},
|
||||
secondaryLabel = {
|
||||
Text(entity?.friendlyName ?: tile?.entityId ?: "")
|
||||
},
|
||||
onClick = onSelectEntity
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon3.cmd_timer_cog,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.refresh_interval)
|
||||
)
|
||||
},
|
||||
secondaryLabel = {
|
||||
Text(
|
||||
intervalToString(LocalContext.current, (tile?.refreshInterval ?: DEFAULT_REFRESH_INTERVAL).toInt())
|
||||
)
|
||||
},
|
||||
onClick = onSelectRefreshInterval
|
||||
)
|
||||
}
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon3.cmd_timer_cog,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.refresh_interval)
|
||||
)
|
||||
},
|
||||
secondaryLabel = {
|
||||
Text(
|
||||
intervalToString(LocalContext.current, (tile?.refreshInterval ?: DEFAULT_REFRESH_INTERVAL).toInt())
|
||||
)
|
||||
},
|
||||
onClick = onSelectRefreshInterval
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.wear.compose.foundation.lazy.items
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Icon
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material.ToggleChip
|
||||
import androidx.wear.compose.material.ToggleChipDefaults
|
||||
|
@ -36,42 +33,29 @@ fun SetFavoritesView(
|
|||
// Remember expanded state of each header
|
||||
val expandedStates = rememberExpandedStates(mainViewModel.supportedDomains())
|
||||
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(
|
||||
state = scalingLazyListState
|
||||
) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.set_favorite)
|
||||
}
|
||||
for (domain in mainViewModel.entitiesByDomainOrder) {
|
||||
val entities = mainViewModel.entitiesByDomain[domain].orEmpty()
|
||||
if (entities.isNotEmpty()) {
|
||||
item {
|
||||
ExpandableListHeader(
|
||||
string = mainViewModel.stringForDomain(domain)!!,
|
||||
key = domain,
|
||||
expandedStates = expandedStates
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = commonR.string.set_favorite)
|
||||
}
|
||||
for (domain in mainViewModel.entitiesByDomainOrder) {
|
||||
val entities = mainViewModel.entitiesByDomain[domain].orEmpty()
|
||||
if (entities.isNotEmpty()) {
|
||||
item {
|
||||
ExpandableListHeader(
|
||||
string = mainViewModel.stringForDomain(domain)!!,
|
||||
key = domain,
|
||||
expandedStates = expandedStates
|
||||
)
|
||||
}
|
||||
if (expandedStates[domain] == true) {
|
||||
items(entities, key = { it.entityId }) { entity ->
|
||||
FavoriteToggleChip(
|
||||
entity = entity,
|
||||
favoriteEntityIds = favoriteEntityIds,
|
||||
onFavoriteSelected = onFavoriteSelected
|
||||
)
|
||||
}
|
||||
if (expandedStates[domain] == true) {
|
||||
items(entities, key = { it.entityId }) { entity ->
|
||||
FavoriteToggleChip(
|
||||
entity = entity,
|
||||
favoriteEntityIds = favoriteEntityIds,
|
||||
onFavoriteSelected = onFavoriteSelected
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,10 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Button
|
||||
import androidx.wear.compose.material.ButtonDefaults
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import com.mikepenz.iconics.compose.Image
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
|
@ -35,64 +32,54 @@ fun SetShortcutsTileView(
|
|||
shortcutEntities: List<SimplifiedEntity>,
|
||||
onShortcutEntitySelectionChange: (Int) -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = commonR.string.shortcuts_choose)
|
||||
}
|
||||
items(shortcutEntities.size) { index ->
|
||||
|
||||
val iconBitmap = getIcon(
|
||||
shortcutEntities[index].icon,
|
||||
shortcutEntities[index].domain,
|
||||
LocalContext.current
|
||||
)
|
||||
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
iconBitmap,
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(commonR.string.shortcut_n, index + 1)
|
||||
)
|
||||
},
|
||||
secondaryLabel = {
|
||||
Text(
|
||||
text = shortcutEntities[index].friendlyName,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
onClick = { onShortcutEntitySelectionChange(index) },
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
if (shortcutEntities.size < 7) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.shortcuts_choose)
|
||||
}
|
||||
items(shortcutEntities.size) { index ->
|
||||
|
||||
val iconBitmap = getIcon(
|
||||
shortcutEntities[index].icon,
|
||||
shortcutEntities[index].domain,
|
||||
LocalContext.current
|
||||
)
|
||||
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
iconBitmap,
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(commonR.string.shortcut_n, index + 1)
|
||||
)
|
||||
},
|
||||
secondaryLabel = {
|
||||
Text(
|
||||
text = shortcutEntities[index].friendlyName,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
onClick = { onShortcutEntitySelectionChange(index) },
|
||||
colors = ChipDefaults.secondaryChipColors()
|
||||
)
|
||||
}
|
||||
if (shortcutEntities.size < 7) {
|
||||
item {
|
||||
Button(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
onClick = { onShortcutEntitySelectionChange(shortcutEntities.size) },
|
||||
colors = ButtonDefaults.primaryButtonColors()
|
||||
) {
|
||||
Image(
|
||||
CommunityMaterial.Icon3.cmd_plus_thick
|
||||
)
|
||||
}
|
||||
Button(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
onClick = { onShortcutEntitySelectionChange(shortcutEntities.size) },
|
||||
colors = ButtonDefaults.primaryButtonColors()
|
||||
) {
|
||||
Image(
|
||||
CommunityMaterial.Icon3.cmd_plus_thick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,9 @@ import androidx.compose.ui.platform.LocalHapticFeedback
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.Icon
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material.ToggleChip
|
||||
import androidx.wear.compose.material.ToggleChipDefaults
|
||||
|
@ -77,237 +74,224 @@ fun SettingsView(
|
|||
onClickTemplateTile: () -> Unit,
|
||||
onAssistantAppAllowed: (Boolean) -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(
|
||||
state = scalingLazyListState
|
||||
) {
|
||||
item {
|
||||
ListHeader(id = commonR.string.favorite_settings)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_star,
|
||||
label = stringResource(commonR.string.favorite),
|
||||
enabled = loadingState == MainViewModel.LoadingState.READY,
|
||||
onClick = onClickSetFavorites
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon.cmd_delete,
|
||||
label = stringResource(commonR.string.clear_favorites),
|
||||
secondaryLabel = stringResource(commonR.string.irreversible),
|
||||
enabled = favorites.isNotEmpty(),
|
||||
onClick = onClearFavorites
|
||||
)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isFavoritesOnly,
|
||||
onCheckedChange = { setFavoritesOnly(it) },
|
||||
label = { Text(stringResource(commonR.string.only_favorites)) },
|
||||
enabled = favorites.isNotEmpty(),
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.switchIcon(isFavoritesOnly),
|
||||
contentDescription = if (isFavoritesOnly) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon2.cmd_home_heart,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.feedback_settings
|
||||
)
|
||||
}
|
||||
item {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isHapticEnabled,
|
||||
onCheckedChange = {
|
||||
onHapticEnabled(it)
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
},
|
||||
label = {
|
||||
Text(stringResource(commonR.string.setting_haptic_label))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset =
|
||||
if (isHapticEnabled) {
|
||||
CommunityMaterial.Icon3.cmd_watch_vibrate
|
||||
} else {
|
||||
CommunityMaterial.Icon3.cmd_watch_vibrate_off
|
||||
},
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.checkboxIcon(isHapticEnabled),
|
||||
contentDescription = if (isHapticEnabled) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isToastEnabled,
|
||||
onCheckedChange = onToastEnabled,
|
||||
label = {
|
||||
Text(stringResource(commonR.string.setting_toast_label))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset =
|
||||
if (isToastEnabled) {
|
||||
CommunityMaterial.Icon3.cmd_message
|
||||
} else {
|
||||
CommunityMaterial.Icon3.cmd_message_off
|
||||
},
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.checkboxIcon(isToastEnabled),
|
||||
contentDescription = if (isHapticEnabled) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.tile_settings
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_video_box,
|
||||
label = stringResource(commonR.string.camera_tiles),
|
||||
onClick = onClickCameraTile
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_star_circle_outline,
|
||||
label = stringResource(commonR.string.shortcut_tiles),
|
||||
onClick = onClickSetShortcuts
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_text_box,
|
||||
label = stringResource(commonR.string.template_tile),
|
||||
onClick = onClickTemplateTile
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.sensors
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon2.cmd_leak,
|
||||
label = stringResource(id = commonR.string.sensor_title),
|
||||
onClick = onClickSensors
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.assist
|
||||
)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isAssistantAppAllowed,
|
||||
onCheckedChange = onAssistantAppAllowed,
|
||||
label = {
|
||||
Text(stringResource(commonR.string.available_as_assistant_app))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_comment_processing_outline,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.switchIcon(isAssistantAppAllowed),
|
||||
contentDescription = if (isFavoritesOnly) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.account
|
||||
)
|
||||
}
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(asset = CommunityMaterial.Icon.cmd_exit_run)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = commonR.string.logout)
|
||||
)
|
||||
},
|
||||
onClick = onClickLogout,
|
||||
colors = ChipDefaults.primaryChipColors(
|
||||
backgroundColor = Color.Red,
|
||||
contentColor = Color.Black
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = commonR.string.favorite_settings)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_star,
|
||||
label = stringResource(commonR.string.favorite),
|
||||
enabled = loadingState == MainViewModel.LoadingState.READY,
|
||||
onClick = onClickSetFavorites
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon.cmd_delete,
|
||||
label = stringResource(commonR.string.clear_favorites),
|
||||
secondaryLabel = stringResource(commonR.string.irreversible),
|
||||
enabled = favorites.isNotEmpty(),
|
||||
onClick = onClearFavorites
|
||||
)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isFavoritesOnly,
|
||||
onCheckedChange = { setFavoritesOnly(it) },
|
||||
label = { Text(stringResource(commonR.string.only_favorites)) },
|
||||
enabled = favorites.isNotEmpty(),
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.switchIcon(isFavoritesOnly),
|
||||
contentDescription = if (isFavoritesOnly) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon2.cmd_home_heart,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.feedback_settings
|
||||
)
|
||||
}
|
||||
item {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isHapticEnabled,
|
||||
onCheckedChange = {
|
||||
onHapticEnabled(it)
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
},
|
||||
label = {
|
||||
Text(stringResource(commonR.string.setting_haptic_label))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset =
|
||||
if (isHapticEnabled) {
|
||||
CommunityMaterial.Icon3.cmd_watch_vibrate
|
||||
} else {
|
||||
CommunityMaterial.Icon3.cmd_watch_vibrate_off
|
||||
},
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.checkboxIcon(isHapticEnabled),
|
||||
contentDescription = if (isHapticEnabled) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isToastEnabled,
|
||||
onCheckedChange = onToastEnabled,
|
||||
label = {
|
||||
Text(stringResource(commonR.string.setting_toast_label))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset =
|
||||
if (isToastEnabled) {
|
||||
CommunityMaterial.Icon3.cmd_message
|
||||
} else {
|
||||
CommunityMaterial.Icon3.cmd_message_off
|
||||
},
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.checkboxIcon(isToastEnabled),
|
||||
contentDescription = if (isHapticEnabled) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.tile_settings
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_video_box,
|
||||
label = stringResource(commonR.string.camera_tiles),
|
||||
onClick = onClickCameraTile
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_star_circle_outline,
|
||||
label = stringResource(commonR.string.shortcut_tiles),
|
||||
onClick = onClickSetShortcuts
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon3.cmd_text_box,
|
||||
label = stringResource(commonR.string.template_tile),
|
||||
onClick = onClickTemplateTile
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.sensors
|
||||
)
|
||||
}
|
||||
item {
|
||||
SecondarySettingsChip(
|
||||
icon = CommunityMaterial.Icon2.cmd_leak,
|
||||
label = stringResource(id = commonR.string.sensor_title),
|
||||
onClick = onClickSensors
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.assist
|
||||
)
|
||||
}
|
||||
item {
|
||||
ToggleChip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
checked = isAssistantAppAllowed,
|
||||
onCheckedChange = onAssistantAppAllowed,
|
||||
label = {
|
||||
Text(stringResource(commonR.string.available_as_assistant_app))
|
||||
},
|
||||
appIcon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon.cmd_comment_processing_outline,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
toggleControl = {
|
||||
Icon(
|
||||
imageVector = ToggleChipDefaults.switchIcon(isAssistantAppAllowed),
|
||||
contentDescription = if (isFavoritesOnly) {
|
||||
stringResource(commonR.string.enabled)
|
||||
} else {
|
||||
stringResource(commonR.string.disabled)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(
|
||||
id = commonR.string.account
|
||||
)
|
||||
}
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(asset = CommunityMaterial.Icon.cmd_exit_run)
|
||||
},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = commonR.string.logout)
|
||||
)
|
||||
},
|
||||
onClick = onClickLogout,
|
||||
colors = ChipDefaults.primaryChipColors(
|
||||
backgroundColor = Color.Red,
|
||||
contentColor = Color.Black
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(commonR.string.application_version)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
text = BuildConfig.VERSION_NAME
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(commonR.string.application_version)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
text = BuildConfig.VERSION_NAME
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,8 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import com.mikepenz.iconics.compose.Image
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
|
@ -31,52 +28,42 @@ fun TemplateTileSettingsView(
|
|||
refreshInterval: Int,
|
||||
onClickRefreshInterval: () -> Unit
|
||||
) {
|
||||
val scalingLazyListState = rememberScalingLazyListState()
|
||||
WearAppTheme {
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scalingLazyListState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scalingLazyListState)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scalingLazyListState) {
|
||||
item {
|
||||
ListHeader(id = R.string.template_tile)
|
||||
}
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon3.cmd_timer_cog,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.refresh_interval)
|
||||
)
|
||||
},
|
||||
secondaryLabel = { Text(intervalToString(LocalContext.current, refreshInterval)) },
|
||||
onClick = onClickRefreshInterval
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(R.string.template_tile_content)
|
||||
}
|
||||
item {
|
||||
Text(stringResource(R.string.template_tile_change_message))
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
templateContent,
|
||||
color = Color.DarkGray
|
||||
)
|
||||
}
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
ListHeader(id = R.string.template_tile)
|
||||
}
|
||||
item {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
icon = {
|
||||
Image(
|
||||
asset = CommunityMaterial.Icon3.cmd_timer_cog,
|
||||
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
|
||||
)
|
||||
},
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.refresh_interval)
|
||||
)
|
||||
},
|
||||
secondaryLabel = { Text(intervalToString(LocalContext.current, refreshInterval)) },
|
||||
onClick = onClickRefreshInterval
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListHeader(R.string.template_tile_content)
|
||||
}
|
||||
item {
|
||||
Text(stringResource(R.string.template_tile_change_message))
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
templateContent,
|
||||
color = Color.DarkGray
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,15 +12,11 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.Button
|
||||
import androidx.wear.compose.material.ButtonDefaults
|
||||
import androidx.wear.compose.material.MaterialTheme
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.Text
|
||||
import io.homeassistant.companion.android.R
|
||||
import io.homeassistant.companion.android.home.views.TimeText
|
||||
import io.homeassistant.companion.android.views.ThemeLazyColumn
|
||||
import io.homeassistant.companion.android.common.R as commonR
|
||||
|
||||
|
@ -30,58 +26,48 @@ fun PhoneInstallView(
|
|||
onRefresh: () -> Unit,
|
||||
onAdvanced: () -> Unit
|
||||
) {
|
||||
val scrollState = rememberScalingLazyListState()
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (scrollState.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = scrollState)
|
||||
ThemeLazyColumn {
|
||||
item {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.app_icon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
text = stringResource(commonR.string.install_phone_to_continue),
|
||||
style = MaterialTheme.typography.title3,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = onInstall,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(commonR.string.install))
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = scrollState) }
|
||||
) {
|
||||
ThemeLazyColumn(state = scrollState) {
|
||||
item {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.app_icon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = onRefresh,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = ButtonDefaults.secondaryButtonColors()
|
||||
) {
|
||||
Text(stringResource(commonR.string.refresh))
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
text = stringResource(commonR.string.install_phone_to_continue),
|
||||
style = MaterialTheme.typography.title3,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = onInstall,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(commonR.string.install))
|
||||
}
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = onRefresh,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = ButtonDefaults.secondaryButtonColors()
|
||||
) {
|
||||
Text(stringResource(commonR.string.refresh))
|
||||
}
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = onAdvanced,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp),
|
||||
colors = ButtonDefaults.secondaryButtonColors()
|
||||
) {
|
||||
Text(stringResource(commonR.string.advanced))
|
||||
}
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = onAdvanced,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp),
|
||||
colors = ButtonDefaults.secondaryButtonColors()
|
||||
) {
|
||||
Text(stringResource(commonR.string.advanced))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,11 @@ import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
|
|||
import androidx.wear.compose.foundation.lazy.ScalingLazyListScope
|
||||
import androidx.wear.compose.foundation.lazy.ScalingLazyListState
|
||||
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import com.google.android.horologist.annotations.ExperimentalHorologistApi
|
||||
import com.google.android.horologist.compose.rotaryinput.rotaryWithScroll
|
||||
import io.homeassistant.companion.android.home.views.TimeText
|
||||
|
||||
@OptIn(ExperimentalHorologistApi::class)
|
||||
@Composable
|
||||
|
@ -20,17 +23,26 @@ fun ThemeLazyColumn(
|
|||
state: ScalingLazyListState = rememberScalingLazyListState(),
|
||||
content: ScalingLazyListScope.() -> Unit
|
||||
) {
|
||||
ScalingLazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.rotaryWithScroll(state),
|
||||
contentPadding = PaddingValues(
|
||||
start = 8.dp,
|
||||
end = 8.dp
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
state = state,
|
||||
content = content
|
||||
)
|
||||
Scaffold(
|
||||
positionIndicator = {
|
||||
if (state.isScrollInProgress) {
|
||||
PositionIndicator(scalingLazyListState = state)
|
||||
}
|
||||
},
|
||||
timeText = { TimeText(scalingLazyListState = state) }
|
||||
) {
|
||||
ScalingLazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.rotaryWithScroll(state),
|
||||
contentPadding = PaddingValues(
|
||||
start = 8.dp,
|
||||
end = 8.dp
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
state = state,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue