This pull request fixes the following issues: - `FiltersActivity` launches a new coroutine to collect the ViewModel state every time the Activity is resumed, without cancelling the previous coroutine. - `FiltersActivity` reloads the filters in `onResume()`, even if loading is already in progress (without cancelling the current loading). This can lead to inconsistent state. List of improvements: - Implement `launchAndRepeatOnLifecycle()` to combine `coroutineScope.launch()` with `repeatOnLifecycle()` for the same `Lifecycle`. Use it in `FiltersActivity` to update the view only when the Activity is visible. - Optimize the filters loading: load them when `FiltersViewModel` is created and when returning from `EditFilterActivity` (when receiving the Activity result). Cancel the load already in progress, if any. - use `MutableStateFlow.update()` to update the state in a thread-safe way. - Turn `FiltersViewModel.deleteFilter()` into a suspending function in order to perform the update in the coroutinescope of the Activity lifecycle, so the View passed as argument doesn't leak. - Wait for an ongoing load operation to complete before performing a delete filter operation, so the state stays consistent. - Add `Intent.withSlideInAnimation()` as a simpler and more flexible alternative to `Activity.startActivityWithSlideInAnimation(Intent)`.
21 lines
724 B
Kotlin
21 lines
724 B
Kotlin
package com.keylesspalace.tusky.util
|
|
|
|
import androidx.lifecycle.Lifecycle
|
|
import androidx.lifecycle.LifecycleOwner
|
|
import androidx.lifecycle.coroutineScope
|
|
import androidx.lifecycle.repeatOnLifecycle
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Job
|
|
import kotlinx.coroutines.launch
|
|
|
|
fun Lifecycle.launchAndRepeatOnLifecycle(
|
|
state: Lifecycle.State = Lifecycle.State.STARTED,
|
|
block: suspend CoroutineScope.() -> Unit
|
|
): Job = coroutineScope.launch {
|
|
repeatOnLifecycle(state, block)
|
|
}
|
|
|
|
fun LifecycleOwner.launchAndRepeatOnLifecycle(
|
|
state: Lifecycle.State = Lifecycle.State.STARTED,
|
|
block: suspend CoroutineScope.() -> Unit
|
|
): Job = lifecycle.launchAndRepeatOnLifecycle(state, block)
|