mirror of https://github.com/Ashinch/ReadYou.git
117 lines
3.6 KiB
Kotlin
117 lines
3.6 KiB
Kotlin
package me.ash.reader.ui.page.home.article
|
|
|
|
import androidx.compose.foundation.lazy.LazyListState
|
|
import androidx.lifecycle.ViewModel
|
|
import androidx.lifecycle.viewModelScope
|
|
import androidx.paging.Pager
|
|
import androidx.paging.PagingConfig
|
|
import androidx.paging.PagingData
|
|
import androidx.paging.cachedIn
|
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.flow.*
|
|
import kotlinx.coroutines.launch
|
|
import me.ash.reader.data.article.ArticleWithFeed
|
|
import me.ash.reader.data.repository.ArticleRepository
|
|
import me.ash.reader.data.repository.RssRepository
|
|
import javax.inject.Inject
|
|
|
|
@HiltViewModel
|
|
class ArticleViewModel @Inject constructor(
|
|
private val articleRepository: ArticleRepository,
|
|
private val rssRepository: RssRepository,
|
|
) : ViewModel() {
|
|
private val _viewState = MutableStateFlow(ArticleViewState())
|
|
val viewState: StateFlow<ArticleViewState> = _viewState.asStateFlow()
|
|
|
|
fun dispatch(action: ArticleViewAction) {
|
|
when (action) {
|
|
is ArticleViewAction.FetchData -> fetchData(
|
|
groupId = action.groupId,
|
|
feedId = action.feedId,
|
|
isStarred = action.isStarred,
|
|
isUnread = action.isUnread,
|
|
)
|
|
is ArticleViewAction.ChangeRefreshing -> changeRefreshing(action.isRefreshing)
|
|
is ArticleViewAction.ScrollToItem -> scrollToItem(action.index)
|
|
is ArticleViewAction.PeekSyncWork -> peekSyncWork()
|
|
}
|
|
}
|
|
|
|
private fun peekSyncWork() {
|
|
_viewState.update {
|
|
it.copy(
|
|
syncWorkInfo = rssRepository.peekWork()
|
|
)
|
|
}
|
|
}
|
|
|
|
private fun fetchData(
|
|
groupId: Int? = null,
|
|
feedId: Int? = null,
|
|
isStarred: Boolean,
|
|
isUnread: Boolean,
|
|
) {
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
articleRepository.pullImportant(isStarred, true)
|
|
.collect { importantList ->
|
|
_viewState.update {
|
|
it.copy(
|
|
filterImportant = importantList.sumOf { it.important },
|
|
)
|
|
}
|
|
}
|
|
}
|
|
_viewState.update {
|
|
it.copy(
|
|
pagingData = Pager(PagingConfig(pageSize = 10)) {
|
|
articleRepository.pullArticles(
|
|
groupId = groupId,
|
|
feedId = feedId,
|
|
isStarred = isStarred,
|
|
isUnread = isUnread,
|
|
)
|
|
}.flow.cachedIn(viewModelScope)
|
|
)
|
|
}
|
|
}
|
|
|
|
private fun scrollToItem(index: Int) {
|
|
viewModelScope.launch {
|
|
_viewState.value.listState.scrollToItem(index)
|
|
}
|
|
}
|
|
|
|
private fun changeRefreshing(isRefreshing: Boolean) {
|
|
_viewState.update {
|
|
it.copy(isRefreshing = isRefreshing)
|
|
}
|
|
}
|
|
}
|
|
|
|
data class ArticleViewState(
|
|
val filterImportant: Int = 0,
|
|
val listState: LazyListState = LazyListState(),
|
|
val isRefreshing: Boolean = false,
|
|
val pagingData: Flow<PagingData<ArticleWithFeed>>? = null,
|
|
val syncWorkInfo: String = "",
|
|
)
|
|
|
|
sealed class ArticleViewAction {
|
|
data class FetchData(
|
|
val groupId: Int? = null,
|
|
val feedId: Int? = null,
|
|
val isStarred: Boolean,
|
|
val isUnread: Boolean,
|
|
) : ArticleViewAction()
|
|
|
|
data class ChangeRefreshing(
|
|
val isRefreshing: Boolean
|
|
) : ArticleViewAction()
|
|
|
|
data class ScrollToItem(
|
|
val index: Int
|
|
) : ArticleViewAction()
|
|
|
|
object PeekSyncWork : ArticleViewAction()
|
|
} |