Skip to content

Commit e2e174d

Browse files
authored
Replace SingleEntityPicker with new EntityPicker (#6293)
* Use new EntityPicker in ManageTiles * Use new EntityPicker in SettingsWearFavority without registries * Use new EntityPicker in AndroidAutoFavorites * Use new EntityPicker in TodoWidgetConfigure * Remove SingleEntityPicker
1 parent 585f124 commit e2e174d

File tree

18 files changed

+423
-328
lines changed

18 files changed

+423
-328
lines changed

app/lint-baseline.xml

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@
492492
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
493493
<location
494494
file="src/main/kotlin/io/homeassistant/companion/android/settings/qs/views/ManageTilesView.kt"
495-
line="59"
495+
line="60"
496496
column="62"/>
497497
</issue>
498498

@@ -1209,7 +1209,7 @@
12091209
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
12101210
<location
12111211
file="src/main/kotlin/io/homeassistant/companion/android/settings/shortcuts/ManageShortcutsViewModel.kt"
1212-
line="207"
1212+
line="216"
12131213
column="13"/>
12141214
</issue>
12151215

@@ -1231,7 +1231,7 @@
12311231
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
12321232
<location
12331233
file="src/main/kotlin/io/homeassistant/companion/android/settings/vehicle/views/AndroidAutoFavoritesView.kt"
1234-
line="41"
1234+
line="42"
12351235
column="5"/>
12361236
</issue>
12371237

@@ -1605,7 +1605,7 @@
16051605
errorLine2=" ~~~~~~~~~~~~~~~">
16061606
<location
16071607
file="src/main/kotlin/io/homeassistant/companion/android/settings/qs/views/ManageTilesView.kt"
1608-
line="50"
1608+
line="51"
16091609
column="5"/>
16101610
</issue>
16111611

@@ -1935,7 +1935,7 @@
19351935
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
19361936
<location
19371937
file="src/full/kotlin/io/homeassistant/companion/android/settings/wear/views/SettingsWearFavoritesView.kt"
1938-
line="41"
1938+
line="42"
19391939
column="5"/>
19401940
</issue>
19411941

@@ -2342,7 +2342,7 @@
23422342
errorLine2=" ~~~~~~~~~~~~">
23432343
<location
23442344
file="src/main/kotlin/io/homeassistant/companion/android/settings/vehicle/views/AndroidAutoFavoritesView.kt"
2345-
line="43"
2345+
line="44"
23462346
column="18"/>
23472347
</issue>
23482348

@@ -2397,7 +2397,7 @@
23972397
errorLine2=" ~~~~~~~~~~~~">
23982398
<location
23992399
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2400-
line="188"
2400+
line="189"
24012401
column="15"/>
24022402
</issue>
24032403

@@ -2408,7 +2408,7 @@
24082408
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
24092409
<location
24102410
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2411-
line="193"
2411+
line="195"
24122412
column="21"/>
24132413
</issue>
24142414

@@ -2419,7 +2419,7 @@
24192419
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
24202420
<location
24212421
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2422-
line="194"
2422+
line="196"
24232423
column="21"/>
24242424
</issue>
24252425

@@ -2430,7 +2430,7 @@
24302430
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
24312431
<location
24322432
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2433-
line="195"
2433+
line="197"
24342434
column="19"/>
24352435
</issue>
24362436

@@ -2441,7 +2441,7 @@
24412441
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
24422442
<location
24432443
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2444-
line="232"
2444+
line="235"
24452445
column="15"/>
24462446
</issue>
24472447

@@ -2452,7 +2452,7 @@
24522452
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
24532453
<location
24542454
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2455-
line="399"
2455+
line="405"
24562456
column="15"/>
24572457
</issue>
24582458

@@ -2463,7 +2463,7 @@
24632463
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
24642464
<location
24652465
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2466-
line="442"
2466+
line="448"
24672467
column="15"/>
24682468
</issue>
24692469

@@ -2474,7 +2474,7 @@
24742474
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
24752475
<location
24762476
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/entity/EntityPicker.kt"
2477-
line="469"
2477+
line="475"
24782478
column="15"/>
24792479
</issue>
24802480

@@ -2654,17 +2654,6 @@
26542654
column="20"/>
26552655
</issue>
26562656

2657-
<issue
2658-
id="ComposeUnstableCollections"
2659-
message="The Compose Compiler cannot infer the stability of a parameter if a List&lt;Entity> is used in it, even if the item type is stable.&#xA;You should use Kotlinx Immutable Collections instead: `entities: ImmutableList&lt;Entity>` or create an `@Immutable` wrapper for this class: `@Immutable data class EntitiesList(val items: List&lt;Entity>)`&#xA;See https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections for more information."
2660-
errorLine1=" entities: List&lt;Entity>,"
2661-
errorLine2=" ~~~~~~~~~~~~">
2662-
<location
2663-
file="src/main/kotlin/io/homeassistant/companion/android/util/compose/SingleEntityPicker.kt"
2664-
line="44"
2665-
column="15"/>
2666-
</issue>
2667-
26682657
<issue
26692658
id="ComposeUnstableCollections"
26702659
message="The Compose Compiler cannot infer the stability of a parameter if a List&lt;String> is used in it, even if the item type is stable.&#xA;You should use Kotlinx Immutable Collections instead: `wifiSsids: ImmutableList&lt;String>` or create an `@Immutable` wrapper for this class: `@Immutable data class WifiSsidsList(val items: List&lt;String>)`&#xA;See https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections for more information."
@@ -2694,7 +2683,7 @@
26942683
errorLine2=" ~~~~~~~~~~~~">
26952684
<location
26962685
file="src/main/kotlin/io/homeassistant/companion/android/widgets/todo/TodoWidgetConfigureActivity.kt"
2697-
line="186"
2686+
line="196"
26982687
column="14"/>
26992688
</issue>
27002689

@@ -2705,10 +2694,43 @@
27052694
errorLine2=" ~~~~~~~~~~~~">
27062695
<location
27072696
file="src/main/kotlin/io/homeassistant/companion/android/widgets/todo/TodoWidgetConfigureActivity.kt"
2708-
line="189"
2697+
line="199"
27092698
column="15"/>
27102699
</issue>
27112700

2701+
<issue
2702+
id="ComposeUnstableCollections"
2703+
message="The Compose Compiler cannot infer the stability of a parameter if a List&lt;EntityRegistryResponse>? is used in it, even if the item type is stable.&#xA;You should use Kotlinx Immutable Collections instead: `entityRegistry: ImmutableList&lt;EntityRegistryResponse>?` or create an `@Immutable` wrapper for this class: `@Immutable data class EntityRegistryList(val items: List&lt;EntityRegistryResponse>?)`&#xA;See https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections for more information."
2704+
errorLine1=" entityRegistry: List&lt;EntityRegistryResponse>? = null,"
2705+
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
2706+
<location
2707+
file="src/main/kotlin/io/homeassistant/companion/android/widgets/todo/TodoWidgetConfigureActivity.kt"
2708+
line="210"
2709+
column="21"/>
2710+
</issue>
2711+
2712+
<issue
2713+
id="ComposeUnstableCollections"
2714+
message="The Compose Compiler cannot infer the stability of a parameter if a List&lt;DeviceRegistryResponse>? is used in it, even if the item type is stable.&#xA;You should use Kotlinx Immutable Collections instead: `deviceRegistry: ImmutableList&lt;DeviceRegistryResponse>?` or create an `@Immutable` wrapper for this class: `@Immutable data class DeviceRegistryList(val items: List&lt;DeviceRegistryResponse>?)`&#xA;See https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections for more information."
2715+
errorLine1=" deviceRegistry: List&lt;DeviceRegistryResponse>? = null,"
2716+
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
2717+
<location
2718+
file="src/main/kotlin/io/homeassistant/companion/android/widgets/todo/TodoWidgetConfigureActivity.kt"
2719+
line="211"
2720+
column="21"/>
2721+
</issue>
2722+
2723+
<issue
2724+
id="ComposeUnstableCollections"
2725+
message="The Compose Compiler cannot infer the stability of a parameter if a List&lt;AreaRegistryResponse>? is used in it, even if the item type is stable.&#xA;You should use Kotlinx Immutable Collections instead: `areaRegistry: ImmutableList&lt;AreaRegistryResponse>?` or create an `@Immutable` wrapper for this class: `@Immutable data class AreaRegistryList(val items: List&lt;AreaRegistryResponse>?)`&#xA;See https://slackhq.github.io/compose-lints/rules/#avoid-using-unstable-collections for more information."
2726+
errorLine1=" areaRegistry: List&lt;AreaRegistryResponse>? = null,"
2727+
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
2728+
<location
2729+
file="src/main/kotlin/io/homeassistant/companion/android/widgets/todo/TodoWidgetConfigureActivity.kt"
2730+
line="212"
2731+
column="19"/>
2732+
</issue>
2733+
27122734
<issue
27132735
id="ComposeUnstableReceiver"
27142736
message="Instance composable functions on non-stable classes will always be recomposed. If possible, make the receiver type stable or refactor this function if that isn&apos;t possible. See https://slackhq.github.io/compose-lints/rules/#unstable-receivers for more information."

app/src/full/kotlin/io/homeassistant/companion/android/settings/wear/views/SettingsWearFavoritesView.kt

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ import androidx.compose.ui.res.stringResource
2121
import androidx.compose.ui.text.font.FontWeight
2222
import androidx.compose.ui.unit.dp
2323
import io.homeassistant.companion.android.common.R as commonR
24+
import io.homeassistant.companion.android.common.compose.theme.HATheme
2425
import io.homeassistant.companion.android.common.data.integration.Entity
2526
import io.homeassistant.companion.android.common.data.integration.friendlyName
2627
import io.homeassistant.companion.android.settings.wear.SettingsWearViewModel
2728
import io.homeassistant.companion.android.util.compose.FavoriteEntityRow
28-
import io.homeassistant.companion.android.util.compose.SingleEntityPicker
29+
import io.homeassistant.companion.android.util.compose.entity.EntityPicker
2930
import io.homeassistant.companion.android.util.plus
3031
import io.homeassistant.companion.android.util.safeBottomPaddingValues
3132
import io.homeassistant.companion.android.util.safeBottomWindowInsets
@@ -101,17 +102,22 @@ fun LoadWearFavoritesSettings(
101102
)
102103
}
103104
item {
104-
SingleEntityPicker(
105-
entities = validEntities,
106-
currentEntity = null,
107-
onEntityCleared = { /* Nothing */ },
108-
onEntitySelected = {
109-
settingsWearViewModel.onEntitySelected(true, it)
110-
return@SingleEntityPicker false // Clear input
111-
},
112-
modifier = Modifier.padding(all = 16.dp),
113-
label = { Text(stringResource(commonR.string.add_favorite)) },
114-
)
105+
// TODO use new theme for Material3 components https://github.com/home-assistant/android/issues/6300
106+
HATheme {
107+
EntityPicker(
108+
entities = validEntities,
109+
selectedEntityId = null,
110+
onEntityCleared = { /* Nothing */ },
111+
onEntitySelectedId = {
112+
settingsWearViewModel.onEntitySelected(true, it)
113+
},
114+
addButtonText = stringResource(commonR.string.add_favorite),
115+
modifier = Modifier.padding(all = 16.dp),
116+
// In order to have the info about the area/device/zone we need the websocket, it would
117+
// requires SettingsWearRepository to be able to use the WebSocket which is a significant
118+
// work.
119+
)
120+
}
115121
}
116122
items(favoriteEntities.size, { favoriteEntities[it] }) { index ->
117123
val favoriteEntityID = favoriteEntities[index].replace("[", "").replace("]", "")

app/src/main/kotlin/io/homeassistant/companion/android/settings/qs/ManageTilesViewModel.kt

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ import io.homeassistant.companion.android.common.data.integration.Entity
2323
import io.homeassistant.companion.android.common.data.integration.getIcon
2424
import io.homeassistant.companion.android.common.data.integration.isUsableInTile
2525
import io.homeassistant.companion.android.common.data.servers.ServerManager
26+
import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse
27+
import io.homeassistant.companion.android.common.data.websocket.impl.entities.DeviceRegistryResponse
28+
import io.homeassistant.companion.android.common.data.websocket.impl.entities.EntityRegistryResponse
2629
import io.homeassistant.companion.android.database.qs.TileDao
2730
import io.homeassistant.companion.android.database.qs.TileEntity
2831
import io.homeassistant.companion.android.database.qs.getHighestInUse
@@ -73,6 +76,7 @@ import io.homeassistant.companion.android.util.icondialog.getIconByMdiName
7376
import io.homeassistant.companion.android.util.icondialog.mdiName
7477
import java.util.concurrent.Executors
7578
import javax.inject.Inject
79+
import kotlinx.coroutines.CancellationException
7680
import kotlinx.coroutines.Dispatchers
7781
import kotlinx.coroutines.async
7882
import kotlinx.coroutines.awaitAll
@@ -147,6 +151,12 @@ class ManageTilesViewModel @Inject constructor(
147151
private set
148152
var sortedEntities by mutableStateOf<List<Entity>>(emptyList())
149153
private set
154+
var entityRegistry by mutableStateOf<List<EntityRegistryResponse>>(emptyList())
155+
private set
156+
var deviceRegistry by mutableStateOf<List<DeviceRegistryResponse>>(emptyList())
157+
private set
158+
var areaRegistry by mutableStateOf<List<AreaRegistryResponse>>(emptyList())
159+
private set
150160
var selectedServerId by mutableIntStateOf(ServerManager.SERVER_ID_ACTIVE)
151161
private set
152162
var selectedIconId by mutableStateOf<String?>(null)
@@ -164,6 +174,9 @@ class ManageTilesViewModel @Inject constructor(
164174
private var selectedTileAdded = false
165175

166176
private val entities = mutableMapOf<Int, List<Entity>>()
177+
private val entityRegistries = mutableMapOf<Int, List<EntityRegistryResponse>>()
178+
private val deviceRegistries = mutableMapOf<Int, List<DeviceRegistryResponse>>()
179+
private val areaRegistries = mutableMapOf<Int, List<AreaRegistryResponse>>()
167180

168181
private val _tileInfoSnackbar = MutableSharedFlow<Int>(replay = 1)
169182
var tileInfoSnackbar = _tileInfoSnackbar.asSharedFlow()
@@ -183,15 +196,13 @@ class ManageTilesViewModel @Inject constructor(
183196
viewModelScope.launch(Dispatchers.IO) {
184197
val servers = serverManager.servers()
185198
this@ManageTilesViewModel.servers = servers
186-
servers.map {
199+
servers.map { server ->
200+
val serverId = server.id
187201
async {
188-
entities[it.id] = try {
189-
serverManager.integrationRepository(it.id).getEntities().orEmpty()
190-
.filter(Entity::isUsableInTile)
191-
} catch (e: Exception) {
192-
Timber.e(e, "Couldn't load entities for server")
193-
emptyList()
194-
}
202+
launch { entities[serverId] = loadEntitiesForServer(serverId) }
203+
launch { entityRegistries[serverId] = loadEntityRegistry(serverId) }
204+
launch { deviceRegistries[serverId] = loadDeviceRegistry(serverId) }
205+
launch { areaRegistries[serverId] = loadAreaRegistry(serverId) }
195206
}
196207
}.awaitAll()
197208
withContext(Dispatchers.Main) {
@@ -240,6 +251,9 @@ class ManageTilesViewModel @Inject constructor(
240251

241252
private fun loadEntities(serverId: Int) {
242253
sortedEntities = entities[serverId] ?: emptyList()
254+
entityRegistry = entityRegistries[serverId] ?: emptyList()
255+
deviceRegistry = deviceRegistries[serverId] ?: emptyList()
256+
areaRegistry = areaRegistries[serverId] ?: emptyList()
243257
}
244258

245259
fun selectEntityId(entityId: String) {
@@ -314,4 +328,41 @@ class ManageTilesViewModel @Inject constructor(
314328
}
315329
}
316330
}
331+
332+
private suspend fun loadEntitiesForServer(serverId: Int): List<Entity> = try {
333+
serverManager.integrationRepository(serverId).getEntities().orEmpty()
334+
.filter(Entity::isUsableInTile)
335+
} catch (e: CancellationException) {
336+
throw e
337+
} catch (e: Exception) {
338+
Timber.e(e, "Couldn't load entities for server")
339+
emptyList()
340+
}
341+
342+
private suspend fun loadEntityRegistry(serverId: Int): List<EntityRegistryResponse> = try {
343+
serverManager.webSocketRepository(serverId).getEntityRegistry().orEmpty()
344+
} catch (e: CancellationException) {
345+
throw e
346+
} catch (e: Exception) {
347+
Timber.e(e, "Couldn't load entity registry for server")
348+
emptyList()
349+
}
350+
351+
private suspend fun loadDeviceRegistry(serverId: Int): List<DeviceRegistryResponse> = try {
352+
serverManager.webSocketRepository(serverId).getDeviceRegistry().orEmpty()
353+
} catch (e: CancellationException) {
354+
throw e
355+
} catch (e: Exception) {
356+
Timber.e(e, "Couldn't load device registry for server")
357+
emptyList()
358+
}
359+
360+
private suspend fun loadAreaRegistry(serverId: Int): List<AreaRegistryResponse> = try {
361+
serverManager.webSocketRepository(serverId).getAreaRegistry().orEmpty()
362+
} catch (e: CancellationException) {
363+
throw e
364+
} catch (e: Exception) {
365+
Timber.e(e, "Couldn't load area registry for server")
366+
emptyList()
367+
}
317368
}

0 commit comments

Comments
 (0)