From 962e0ee8dc2635e523babe4abd62526bafde9ced Mon Sep 17 00:00:00 2001 From: Ash Date: Mon, 16 May 2022 10:57:40 +0800 Subject: [PATCH] Unified CoroutineDispatcher --- .../ui/page/home/feeds/FeedsViewModel.kt | 16 ++++++---- .../feeds/option/feed/FeedOptionViewModel.kt | 24 +++++++++------ .../option/group/GroupOptionViewModel.kt | 30 +++++++++++-------- .../feeds/subscribe/SubscribeViewModel.kt | 11 ++++--- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt index 43c9f63..6030473 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt @@ -5,12 +5,14 @@ import androidx.compose.foundation.lazy.LazyListState import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import me.ash.reader.R import me.ash.reader.data.entity.Account import me.ash.reader.data.entity.GroupWithFeed +import me.ash.reader.data.module.DispatcherDefault +import me.ash.reader.data.module.DispatcherIO import me.ash.reader.data.repository.AccountRepository import me.ash.reader.data.repository.OpmlRepository import me.ash.reader.data.repository.RssRepository @@ -24,6 +26,10 @@ class FeedsViewModel @Inject constructor( private val rssRepository: RssRepository, private val opmlRepository: OpmlRepository, private val stringsRepository: StringsRepository, + @DispatcherDefault + private val dispatcherDefault: CoroutineDispatcher, + @DispatcherIO + private val dispatcherIO: CoroutineDispatcher, ) : ViewModel() { private val _viewState = MutableStateFlow(FeedsViewState()) val viewState: StateFlow = _viewState.asStateFlow() @@ -38,7 +44,7 @@ class FeedsViewModel @Inject constructor( } private fun fetchAccount() { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { _viewState.update { it.copy( account = accountRepository.getCurrentAccount() @@ -48,7 +54,7 @@ class FeedsViewModel @Inject constructor( } private fun exportAsOpml(callback: (String) -> Unit = {}) { - viewModelScope.launch(Dispatchers.Default) { + viewModelScope.launch(dispatcherDefault) { try { callback(opmlRepository.saveToString()) } catch (e: Exception) { @@ -58,7 +64,7 @@ class FeedsViewModel @Inject constructor( } private fun fetchData(filterState: FilterState) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { pullFeeds( isStarred = filterState.filter.isStarred(), isUnread = filterState.filter.isUnread(), @@ -118,7 +124,7 @@ class FeedsViewModel @Inject constructor( } }.catch { Log.e("RLog", "catch in articleRepository.pullFeeds(): ${it.message}") - }.flowOn(Dispatchers.Default).collect() + }.flowOn(dispatcherDefault).collect() } private fun scrollToItem(index: Int) { diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/feed/FeedOptionViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/feed/FeedOptionViewModel.kt index d31c510..bbe0aef 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/feed/FeedOptionViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/feed/FeedOptionViewModel.kt @@ -7,8 +7,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.accompanist.pager.ExperimentalPagerApi import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -17,6 +17,8 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.ash.reader.data.entity.Feed import me.ash.reader.data.entity.Group +import me.ash.reader.data.module.DispatcherIO +import me.ash.reader.data.module.DispatcherMain import me.ash.reader.data.repository.RssRepository import javax.inject.Inject @@ -27,12 +29,16 @@ import javax.inject.Inject @HiltViewModel class FeedOptionViewModel @Inject constructor( private val rssRepository: RssRepository, + @DispatcherMain + private val dispatcherMain: CoroutineDispatcher, + @DispatcherIO + private val dispatcherIO: CoroutineDispatcher, ) : ViewModel() { private val _viewState = MutableStateFlow(FeedOptionViewState()) val viewState: StateFlow = _viewState.asStateFlow() init { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().pullGroups().collect { groups -> _viewState.update { it.copy( @@ -121,7 +127,7 @@ class FeedOptionViewModel @Inject constructor( } private fun selectedGroup(groupId: String) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { _viewState.value.feed?.let { rssRepository.get().updateFeed( it.copy( @@ -134,7 +140,7 @@ class FeedOptionViewModel @Inject constructor( } private fun changeParseFullContentPreset() { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { _viewState.value.feed?.let { rssRepository.get().updateFeed( it.copy( @@ -147,7 +153,7 @@ class FeedOptionViewModel @Inject constructor( } private fun changeAllowNotificationPreset() { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { _viewState.value.feed?.let { rssRepository.get().updateFeed( it.copy( @@ -161,9 +167,9 @@ class FeedOptionViewModel @Inject constructor( private fun delete(callback: () -> Unit = {}) { _viewState.value.feed?.let { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().deleteFeed(it) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } @@ -204,9 +210,9 @@ class FeedOptionViewModel @Inject constructor( private fun clear(callback: () -> Unit = {}) { _viewState.value.feed?.let { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().deleteArticles(feed = it) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/group/GroupOptionViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/group/GroupOptionViewModel.kt index b696c8d..59415b4 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/group/GroupOptionViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/option/group/GroupOptionViewModel.kt @@ -7,8 +7,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.accompanist.pager.ExperimentalPagerApi import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -16,6 +16,8 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.ash.reader.data.entity.Group +import me.ash.reader.data.module.DispatcherIO +import me.ash.reader.data.module.DispatcherMain import me.ash.reader.data.repository.RssRepository import javax.inject.Inject @@ -26,12 +28,16 @@ import javax.inject.Inject @HiltViewModel class GroupOptionViewModel @Inject constructor( private val rssRepository: RssRepository, + @DispatcherMain + private val dispatcherMain: CoroutineDispatcher, + @DispatcherIO + private val dispatcherIO: CoroutineDispatcher, ) : ViewModel() { private val _viewState = MutableStateFlow(GroupOptionViewState()) val viewState: StateFlow = _viewState.asStateFlow() init { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().pullGroups().collect { groups -> _viewState.update { it.copy( @@ -106,9 +112,9 @@ class GroupOptionViewModel @Inject constructor( private fun allAllowNotification(isNotification: Boolean, callback: () -> Unit = {}) { _viewState.value.group?.let { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().groupAllowNotification(it, isNotification) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } @@ -125,9 +131,9 @@ class GroupOptionViewModel @Inject constructor( private fun allParseFullContent(isFullContent: Boolean, callback: () -> Unit = {}) { _viewState.value.group?.let { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().groupParseFullContent(it, isFullContent) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } @@ -144,9 +150,9 @@ class GroupOptionViewModel @Inject constructor( private fun delete(callback: () -> Unit = {}) { _viewState.value.group?.let { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().deleteGroup(it) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } @@ -179,9 +185,9 @@ class GroupOptionViewModel @Inject constructor( private fun clear(callback: () -> Unit = {}) { _viewState.value.group?.let { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().deleteArticles(group = it) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } @@ -191,9 +197,9 @@ class GroupOptionViewModel @Inject constructor( private fun allMoveToGroup(callback: () -> Unit) { _viewState.value.group?.let { group -> _viewState.value.targetGroup?.let { targetGroup -> - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { rssRepository.get().groupMoveToTargetGroup(group, targetGroup) - withContext(Dispatchers.Main) { + withContext(dispatcherMain) { callback() } } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt index 2b4f807..9bdc1f1 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.accompanist.pager.ExperimentalPagerApi import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.flow.* @@ -14,6 +14,7 @@ import me.ash.reader.R import me.ash.reader.data.entity.Article import me.ash.reader.data.entity.Feed import me.ash.reader.data.entity.Group +import me.ash.reader.data.module.DispatcherIO import me.ash.reader.data.repository.OpmlRepository import me.ash.reader.data.repository.RssHelper import me.ash.reader.data.repository.RssRepository @@ -29,6 +30,8 @@ class SubscribeViewModel @Inject constructor( private val rssRepository: RssRepository, private val rssHelper: RssHelper, private val stringsRepository: StringsRepository, + @DispatcherIO + private val dispatcherIO: CoroutineDispatcher, ) : ViewModel() { private val _viewState = MutableStateFlow(SubscribeViewState()) val viewState: StateFlow = _viewState.asStateFlow() @@ -77,7 +80,7 @@ class SubscribeViewModel @Inject constructor( } private fun importFromInputStream(inputStream: InputStream) { - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { try { opmlRepository.saveToDatabase(inputStream) rssRepository.get().doSync() @@ -90,7 +93,7 @@ class SubscribeViewModel @Inject constructor( private fun subscribe() { val feed = _viewState.value.feed ?: return val articles = _viewState.value.articles - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { val groupId = async { _viewState.value.selectedGroupId } @@ -145,7 +148,7 @@ class SubscribeViewModel @Inject constructor( private fun search() { searchJob?.cancel() - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch(dispatcherIO) { try { _viewState.update { it.copy(