amethyst/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt

165 wiersze
5.0 KiB
Kotlin

package com.vitorpamplona.amethyst.ui.screen
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Button
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import kotlinx.coroutines.delay
@Composable
fun FeedView(
viewModel: FeedViewModel,
accountViewModel: AccountViewModel,
navController: NavController,
routeForLastRead: String?
) {
val feedState by viewModel.feedContent.collectAsState()
var isRefreshing by remember { mutableStateOf(false) }
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
LaunchedEffect(isRefreshing) {
if (isRefreshing) {
viewModel.refresh()
isRefreshing = false
}
}
SwipeRefresh(
state = swipeRefreshState,
onRefresh = {
isRefreshing = true
},
) {
Column() {
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
when (state) {
is FeedState.Empty -> {
FeedEmpty {
isRefreshing = true
}
}
is FeedState.FeedError -> {
FeedError(state.errorMessage) {
isRefreshing = true
}
}
is FeedState.Loaded -> {
FeedLoaded(
state,
routeForLastRead,
accountViewModel,
navController
)
}
is FeedState.Loading -> {
LoadingFeed()
}
}
}
}
}
}
@Composable
private fun FeedLoaded(
state: FeedState.Loaded,
routeForLastRead: String?,
accountViewModel: AccountViewModel,
navController: NavController
) {
val listState = rememberLazyListState()
LazyColumn(
contentPadding = PaddingValues(
top = 10.dp,
bottom = 10.dp
),
state = listState
) {
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { index, item ->
NoteCompose(
item,
isBoostedNote = false,
routeForLastRead = routeForLastRead,
accountViewModel = accountViewModel,
navController = navController
)
}
}
}
@Composable
fun LoadingFeed() {
Column(
Modifier
.fillMaxHeight()
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(stringResource(R.string.loading_feed))
}
}
@Composable
fun FeedError(errorMessage: String, onRefresh: () -> Unit) {
Column(
Modifier
.fillMaxHeight()
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text("${stringResource(R.string.error_loading_replies)} $errorMessage")
Button(
modifier = Modifier.align(Alignment.CenterHorizontally),
onClick = onRefresh
) {
Text(text = stringResource(R.string.try_again))
}
}
}
@Composable
fun FeedEmpty(onRefresh: () -> Unit) {
Column(
Modifier
.fillMaxHeight()
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(stringResource(R.string.feed_is_empty))
OutlinedButton(onClick = onRefresh) {
Text(text = stringResource(R.string.refresh))
}
}
}