Prevent parallel loading and fix duplicate ViewModel state collection in FiltersActivity (#4472)
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)`.
This commit is contained in:
parent
0483440381
commit
d200d1e15e
4 changed files with 101 additions and 57 deletions
|
|
@ -12,10 +12,13 @@ import androidx.lifecycle.LifecycleEventObserver
|
|||
import com.keylesspalace.tusky.BaseActivity
|
||||
|
||||
fun Activity.startActivityWithSlideInAnimation(intent: Intent) {
|
||||
startActivity(intent.withSlideInAnimation())
|
||||
}
|
||||
|
||||
fun Intent.withSlideInAnimation(): Intent {
|
||||
// the new transition api needs to be called by the activity that is the result of the transition,
|
||||
// so we pass a flag that BaseActivity will respect.
|
||||
intent.putExtra(BaseActivity.OPEN_WITH_SLIDE_IN, true)
|
||||
startActivity(intent)
|
||||
return putExtra(BaseActivity.OPEN_WITH_SLIDE_IN, true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue