android
android copied to clipboard
Move complex logic out of MainView into MainViewModel using coroutine
Summary
This PR has been made mostly using Claude asking it to move the complex logic out of the MainView since it was causing crashes.
This is a quick attempt to fix the crashes while we actually need to do a bigger refactor that would improve the code and maintainability.
The crashes were

Checklist
- [ ] New or updated tests have been added to cover the changes following the testing guidelines.
- [ ] The code follows the project's code style and best_practices.
- [ ] The changes have been thoroughly tested, and edge cases have been considered.
- [ ] Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.
Any other notes
I did some quick tests and it seems to work like before, but since I'm not a big user of the wear app, I would like @dshokouhi opinion on this.
Got the following crash while testing, everything loaded and i scrolled down then it froze and got this
2025-11-19 10:20:43.699 25395-25395 AndroidRuntime pid-25395 E FATAL EXCEPTION: main (Ask Gemini)
Process: io.homeassistant.companion.android.debug, PID: 25395
java.lang.IndexOutOfBoundsException: index (1) is out of bound of [0, 0)
at androidx.compose.runtime.snapshots.SnapshotStateListKt.validateRange(SnapshotStateList.kt:277)
at androidx.compose.runtime.snapshots.SnapshotStateListKt.access$validateRange(SnapshotStateList.kt:1)
at androidx.compose.runtime.snapshots.StateListIterator.next(SnapshotStateList.kt:320)
at io.homeassistant.companion.android.home.views.MainViewKt.MainView$lambda$4$0$0(MainView.kt:365)
at io.homeassistant.companion.android.home.views.MainViewKt.$r8$lambda$q0Pq-izE1L_7I5qbvDlK4CgY86I(Unknown Source:0)
at io.homeassistant.companion.android.home.views.MainViewKt$$ExternalSyntheticLambda21.invoke(D8$$SyntheticClass:0)
at androidx.wear.compose.foundation.lazy.ScalingLazyColumnKt$ScalingLazyColumn$3.invoke$lambda$5$lambda$3$lambda$2(ScalingLazyColumn.kt:728)
at androidx.wear.compose.foundation.lazy.ScalingLazyColumnKt$ScalingLazyColumn$3.$r8$lambda$7ACB8HPmCmWRuxUn7VEPWZKQxhg(Unknown Source:0)
at androidx.wear.compose.foundation.lazy.ScalingLazyColumnKt$ScalingLazyColumn$3$$ExternalSyntheticLambda1.invoke(D8$$SyntheticClass:0)
at androidx.compose.foundation.lazy.LazyListIntervalContent.<init>(LazyListIntervalContent.kt:36)
at androidx.compose.foundation.lazy.LazyListItemProviderKt.rememberLazyListItemProviderLambda$lambda$2$lambda$0(LazyListItemProvider.kt:48)
at androidx.compose.foundation.lazy.LazyListItemProviderKt.$r8$lambda$KY-c3TpgyZTIhfXmznGuPwy1AMQ(Unknown Source:0)
at androidx.compose.foundation.lazy.LazyListItemProviderKt$$ExternalSyntheticLambda0.invoke(D8$$SyntheticClass:0)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2495)
at androidx.compose.runtime.DerivedSnapshotState.currentRecord(DerivedState.kt:210)
at androidx.compose.runtime.DerivedSnapshotState.current(DerivedState.kt:176)
at androidx.compose.runtime.DerivedSnapshotState$ResultRecord.readableHash(DerivedState.kt:152)
at androidx.compose.runtime.DerivedSnapshotState$ResultRecord.isValid(DerivedState.kt:123)
at androidx.compose.runtime.DerivedSnapshotState.currentRecord(DerivedState.kt:184)
at androidx.compose.runtime.DerivedSnapshotState.getCurrentRecord(DerivedState.kt:292)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.recordInvalidation(SnapshotStateObserver.kt:548)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.drainChanges(SnapshotStateObserver.kt:72)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.applyObserver$lambda$0(SnapshotStateObserver.kt:51)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.$r8$lambda$O21urw2Cx4LPNsPHLB96kXfU0Q8(Unknown Source:0)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$$ExternalSyntheticLambda1.invoke(D8$$SyntheticClass:0)
at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot(Snapshot.kt:1980)
at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot(Snapshot.kt:1994)
at androidx.compose.runtime.snapshots.SnapshotKt.access$advanceGlobalSnapshot(Snapshot.kt:1)
at androidx.compose.runtime.snapshots.GlobalSnapshot.notifyObjectsInitialized$runtime(Snapshot.kt:1535)
at androidx.compose.runtime.snapshots.Snapshot$Companion.notifyObjectsInitialized(Snapshot.kt:666)
at androidx.compose.runtime.DerivedSnapshotState.currentRecord(DerivedState.kt:252)
at androidx.compose.runtime.DerivedSnapshotState.current(DerivedState.kt:176)
at androidx.compose.runtime.DerivedSnapshotState$ResultRecord.readableHash(DerivedState.kt:152)
at androidx.compose.runtime.DerivedSnapshotState$ResultRecord.isValid(DerivedState.kt:123)
at androidx.compose.runtime.DerivedSnapshotState.currentRecord(DerivedState.kt:184)
at androidx.compose.runtime.DerivedSnapshotState.getValue(DerivedState.kt:285)
at androidx.compose.foundation.lazy.LazyListItemProviderKt$rememberLazyListItemProviderLambda$1$1.get(LazyListItemProvider.kt:61)