Add swipe to refresh in TimelineScreen with basic item display and refresh

This commit is contained in:
Shinokuni 2023-07-23 17:18:03 +02:00
parent bda5896413
commit 1a37401139
5 changed files with 85 additions and 7 deletions

View File

@ -71,6 +71,8 @@ dependencies {
implementation 'androidx.activity:activity-compose:1.7.2'
implementation 'androidx.compose.material3:material3'
implementation "com.google.accompanist:accompanist-swiperefresh:0.30.1"
def voyager = "1.0.0-rc03"
implementation "cafe.adriel.voyager:voyager-navigator:$voyager"
implementation "cafe.adriel.voyager:voyager-bottom-sheet-navigator:$voyager"

View File

@ -11,7 +11,7 @@ import org.koin.dsl.module
val composeAppModule = module {
viewModel { TimelineViewModel(get()) }
viewModel { TimelineViewModel(get(), get()) }
viewModel { FeedsViewModel(get()) }

View File

@ -1,8 +1,16 @@
package com.readrops.app.compose.timelime
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import cafe.adriel.voyager.androidx.AndroidScreen
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import org.koin.androidx.compose.getViewModel
@ -11,9 +19,34 @@ class TimelineScreen : AndroidScreen() {
@Composable
override fun Content() {
val viewModel = getViewModel<TimelineViewModel>()
val state by viewModel.timelineState.collectAsState()
val isRefreshing by viewModel.isRefreshing.collectAsState()
Column {
TimelineItem()
val swipeToRefreshState = rememberSwipeRefreshState(isRefreshing)
SwipeRefresh(
state = swipeToRefreshState,
onRefresh = {
viewModel.refreshTimeline()
},
modifier = Modifier.fillMaxSize()
) {
when (state) {
is TimelineState.ErrorState -> {
Text(text = "error")
}
TimelineState.InitialState -> {}
is TimelineState.LoadedState -> {
LazyColumn {
items(
items = (state as TimelineState.LoadedState).items
) {
TimelineItem()
}
}
}
}
}
}
}

View File

@ -1,12 +1,52 @@
package com.readrops.app.compose.timelime
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.readrops.app.compose.repositories.BaseRepository
import com.readrops.db.Database
import com.readrops.db.entities.Item
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.launch
class TimelineViewModel(
val database: Database
private val database: Database,
private val repository: BaseRepository,
) : ViewModel() {
private val _timelineState = MutableStateFlow<TimelineState>(TimelineState.InitialState)
val timelineState = _timelineState.asStateFlow()
private var _isRefreshing = MutableStateFlow(false)
val isRefreshing = _isRefreshing.asStateFlow()
init {
viewModelScope.launch(context = Dispatchers.IO) {
database.newItemDao().selectAll()
.catch { _timelineState.value = TimelineState.ErrorState(Exception(it)) }
.collect {
_timelineState.value = TimelineState.LoadedState(it)
}
}
}
fun refreshTimeline() {
_isRefreshing.value = true
viewModelScope.launch(context = Dispatchers.IO) {
repository.synchronize(null) {
}
_isRefreshing.value = false
}
}
}
sealed class TimelineState {
object InitialState : TimelineState()
data class ErrorState(val exception: Exception) : TimelineState()
data class LoadedState(val items: List<Item>) : TimelineState()
}
}

View File

@ -1,10 +1,13 @@
package com.readrops.db.dao.newdao
import androidx.room.Dao
import androidx.room.Query
import com.readrops.db.entities.Item
import kotlinx.coroutines.flow.Flow
@Dao
abstract class NewItemDao : NewBaseDao<Item> {
@Query("Select * From Item")
abstract fun selectAll(): Flow<List<Item>>
}