@@ -40,8 +40,9 @@ import com.readrops.db.pojo.ItemWithFeed
4040import com.readrops.db.queries.ItemSelectionQueryBuilder
4141import com.readrops.db.queries.ItemsQueryBuilder
4242import kotlinx.coroutines.CoroutineDispatcher
43+ import kotlinx.coroutines.DelicateCoroutinesApi
4344import kotlinx.coroutines.Dispatchers
44- import kotlinx.coroutines.NonCancellable
45+ import kotlinx.coroutines.GlobalScope
4546import kotlinx.coroutines.flow.Flow
4647import kotlinx.coroutines.flow.MutableStateFlow
4748import kotlinx.coroutines.flow.SharingStarted
@@ -51,7 +52,6 @@ import kotlinx.coroutines.flow.map
5152import kotlinx.coroutines.flow.stateIn
5253import kotlinx.coroutines.flow.update
5354import kotlinx.coroutines.launch
54- import kotlinx.coroutines.withContext
5555import org.koin.core.component.KoinComponent
5656import org.koin.core.component.get
5757import org.koin.core.parameter.parametersOf
@@ -92,6 +92,7 @@ class ItemScreenModel(
9292 )
9393 )
9494 )
95+
9596 // based type is Flow because with StateFlow when coming back from process death, pager doesn't resume
9697 // it might be due to stateIn() overlapping cachedIn(), but not sure
9798 var itemState: Flow <PagingData <ItemWithFeed >> = _itemState .asStateFlow()
@@ -360,23 +361,29 @@ class ItemScreenModel(
360361 item, context, useCustomShareIntentTpl.value, customShareIntentTpl.value
361362 )
362363
364+ @OptIn(DelicateCoroutinesApi ::class )
363365 override fun onDispose () {
364- screenModelScope.launch(dispatcher) {
365- withContext(NonCancellable ) {
366- repository.setItemsRead(
367- items = state.value.stateChanges
368- .filter { it.readChange }
369- .map { it.item }
370- )
366+ // Use GlobalScope instead of NonCancellable
367+ // It seems that NonCancellable is not is sufficiently non cancellable
368+ // I ran multiple times into very frustrating situations where items were not set read
369+ // The risk of leak here is mitigated by the fact that only one shot operations are performed
370+ // If the coroutine is cancelled for whatever reason, only items state will be lost, which is not a big deal
371+ // and should happen very rarely
372+ GlobalScope .launch(dispatcher) {
373+ repository.setItemsRead(
374+ items = state.value.stateChanges
375+ .filter { it.readChange }
376+ .map { it.item }
377+ )
378+
379+ state.value.stateChanges
380+ .filter { it.starChange }
381+ .forEach {
382+ repository.setItemStarState(it.item.apply {
383+ isStarred = ! isStarred
384+ })
385+ }
371386
372- state.value.stateChanges
373- .filter { it.starChange }
374- .forEach {
375- repository.setItemStarState(it.item.apply {
376- isStarred = ! isStarred
377- })
378- }
379- }
380387 }
381388 }
382389}
0 commit comments