android icon indicating copy to clipboard operation
android copied to clipboard

Move complex logic out of MainView into MainViewModel using coroutine

Open TimoPtr opened this issue 3 months ago • 1 comments

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 image image

image

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.

TimoPtr avatar Nov 13 '25 10:11 TimoPtr

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)

dshokouhi avatar Nov 19 '25 18:11 dshokouhi