diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedView.kt index df4fa0ebf..9b77d4156 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedView.kt @@ -2,22 +2,26 @@ package com.vitorpamplona.amethyst.ui.screen import androidx.compose.animation.Crossfade import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState 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.unit.dp import androidx.navigation.NavController -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.vitorpamplona.amethyst.ui.note.BadgeCompose import com.vitorpamplona.amethyst.ui.note.BoostSetCompose import com.vitorpamplona.amethyst.ui.note.LikeSetCompose @@ -27,40 +31,31 @@ import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.ZapSetCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +@OptIn(ExperimentalMaterialApi::class) @Composable fun CardFeedView(viewModel: CardFeedViewModel, accountViewModel: AccountViewModel, navController: NavController, routeForLastRead: String) { val feedState by viewModel.feedContent.collectAsState() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } - - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { + Box(Modifier.pullRefresh(pullRefreshState)) { Column() { Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is CardFeedState.Empty -> { FeedEmpty { - isRefreshing = true + refreshing = true } } is CardFeedState.FeedError -> { FeedError(state.errorMessage) { - isRefreshing = true + refreshing = true } } is CardFeedState.Loaded -> { + refreshing = false FeedLoaded( state, accountViewModel, @@ -74,6 +69,8 @@ fun CardFeedView(viewModel: CardFeedViewModel, accountViewModel: AccountViewMode } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt index 805f9abc5..8ba6eb059 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt @@ -62,8 +62,7 @@ fun ChatroomFeedView(viewModel: FeedViewModel, accountViewModel: AccountViewMode reverseLayout = true, state = listState ) { - var previousDate: String = "" - itemsIndexed(state.feed.value, key = { index, item -> item.idHex }) { index, item -> + itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item -> ChatroomMessageCompose(item, routeForLastRead, accountViewModel = accountViewModel, navController = navController, onWantsToReply = onWantsToReply) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt index 1bc51f58d..743bd4f5c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomListFeedView.kt @@ -2,11 +2,16 @@ package com.vitorpamplona.amethyst.ui.screen import androidx.compose.animation.Crossfade import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState @@ -14,18 +19,18 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.vitorpamplona.amethyst.NotificationCache import com.vitorpamplona.amethyst.ui.note.ChatroomCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +@OptIn(ExperimentalMaterialApi::class) @Composable fun ChatroomListFeedView( viewModel: FeedViewModel, @@ -35,24 +40,11 @@ fun ChatroomListFeedView( ) { val feedState by viewModel.feedContent.collectAsStateWithLifecycle() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - val coroutineScope = rememberCoroutineScope() - - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } - - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { + Box(Modifier.pullRefresh(pullRefreshState)) { Column() { Crossfade( targetState = feedState, @@ -61,17 +53,18 @@ fun ChatroomListFeedView( when (state) { is FeedState.Empty -> { FeedEmpty { - isRefreshing = true + refreshing = true } } is FeedState.FeedError -> { FeedError(state.errorMessage) { - isRefreshing = true + refreshing = true } } is FeedState.Loaded -> { + refreshing = false FeedLoaded(state, accountViewModel, navController, markAsRead) } @@ -81,6 +74,8 @@ fun ChatroomListFeedView( } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } } @@ -103,11 +98,9 @@ private fun FeedLoaded( if (markAsRead.value) { for (note in state.feed.value) { note.event?.let { - var route = "" val channel = note.channel() - - if (channel != null) { - route = "Channel/${channel.idHex}" + val route = if (channel != null) { + "Channel/${channel.idHex}" } else { val replyAuthorBase = note.mentions?.first() var userToComposeOn = note.author!! @@ -116,7 +109,7 @@ private fun FeedLoaded( userToComposeOn = replyAuthorBase } } - route = "Room/${userToComposeOn.pubkeyHex}" + "Room/${userToComposeOn.pubkeyHex}" } notificationCache.cache.markAsRead(route, it.createdAt(), context) @@ -136,7 +129,7 @@ private fun FeedLoaded( itemsIndexed( state.feed.value, key = { index, item -> if (index == 0) index else item.idHex } - ) { index, item -> + ) { _, item -> ChatroomCompose( item, accountViewModel = accountViewModel, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt index ea412e861..aed87aaee 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt @@ -3,6 +3,7 @@ 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.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxHeight @@ -11,10 +12,13 @@ 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.ExperimentalMaterialApi import androidx.compose.material.OutlinedButton import androidx.compose.material.Text +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState 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 @@ -25,12 +29,11 @@ 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 +@OptIn(ExperimentalMaterialApi::class) @Composable fun FeedView( viewModel: FeedViewModel, @@ -41,36 +44,31 @@ fun FeedView( ) { val feedState by viewModel.feedContent.collectAsState() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } - - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { - Column() { - Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> + Box(Modifier.pullRefresh(pullRefreshState)) { + Column { + Crossfade( + targetState = feedState, + animationSpec = tween(durationMillis = 100) + ) { state -> when (state) { is FeedState.Empty -> { FeedEmpty { - isRefreshing = true + refreshing = true } } + is FeedState.FeedError -> { FeedError(state.errorMessage) { - isRefreshing = true + refreshing = true } } + is FeedState.Loaded -> { + refreshing = false FeedLoaded( state, routeForLastRead, @@ -79,12 +77,15 @@ fun FeedView( scrollStateKey ) } + is FeedState.Loading -> { LoadingFeed() } } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } } @@ -109,7 +110,7 @@ private fun FeedLoaded( ), state = listState ) { - itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { index, item -> + itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item -> NoteCompose( item, isBoostedNote = false, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/LnZapFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/LnZapFeedView.kt index 4570bef66..d4d8767bd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/LnZapFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/LnZapFeedView.kt @@ -2,59 +2,54 @@ package com.vitorpamplona.amethyst.ui.screen import androidx.compose.animation.Crossfade import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState 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.unit.dp import androidx.navigation.NavController -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.vitorpamplona.amethyst.ui.note.ZapNoteCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +@OptIn(ExperimentalMaterialApi::class) @Composable fun LnZapFeedView(viewModel: LnZapFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) { val feedState by viewModel.feedContent.collectAsState() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } - - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { + Box(Modifier.pullRefresh(pullRefreshState)) { Column() { Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is LnZapFeedState.Empty -> { FeedEmpty { - isRefreshing = true + refreshing = true } } is LnZapFeedState.FeedError -> { FeedError(state.errorMessage) { - isRefreshing = true + refreshing = true } } is LnZapFeedState.Loaded -> { + refreshing = false LnZapFeedLoaded(state, accountViewModel, navController) } is LnZapFeedState.Loading -> { @@ -63,6 +58,8 @@ fun LnZapFeedView(viewModel: LnZapFeedViewModel, accountViewModel: AccountViewMo } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/RelayFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/RelayFeedView.kt index 2461b982f..2b27ef43c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/RelayFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/RelayFeedView.kt @@ -1,24 +1,28 @@ package com.vitorpamplona.amethyst.ui.screen +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState 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.unit.dp import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.navigation.NavController -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.vitorpamplona.amethyst.model.RelayInfo import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.UserState @@ -101,6 +105,7 @@ class RelayFeedViewModel : ViewModel() { } } +@OptIn(ExperimentalMaterialApi::class) @Composable fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) { val accountState by accountViewModel.accountLiveData.observeAsState() @@ -108,9 +113,6 @@ fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewMo val feedState by viewModel.feedContent.collectAsState() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) - var wantsToAddRelay by remember { mutableStateOf("") } @@ -119,19 +121,11 @@ fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewMo NewRelayListView({ wantsToAddRelay = "" }, account, wantsToAddRelay) } - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { + Box(Modifier.pullRefresh(pullRefreshState)) { Column() { val listState = rememberLazyListState() @@ -153,5 +147,7 @@ fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewMo } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt index aeffef514..d9a5a667b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt @@ -5,6 +5,7 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -16,12 +17,16 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.Divider +import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -44,8 +49,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController import coil.compose.AsyncImage -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.model.BadgeDefinitionEvent @@ -65,42 +68,33 @@ import com.vitorpamplona.amethyst.ui.note.timeAgo import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.delay +@OptIn(ExperimentalMaterialApi::class) @Composable fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: AccountViewModel, navController: NavController) { val feedState by viewModel.feedContent.collectAsState() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) - val listState = rememberLazyListState() - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { + Box(Modifier.pullRefresh(pullRefreshState)) { Column() { Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is FeedState.Empty -> { FeedEmpty { - isRefreshing = true + refreshing = true } } is FeedState.FeedError -> { FeedError(state.errorMessage) { - isRefreshing = true + refreshing = true } } is FeedState.Loaded -> { + refreshing = false LaunchedEffect(noteId) { // waits to load the thread to scroll to item. delay(100) @@ -163,6 +157,8 @@ fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: A } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt index ed9b04b7c..3452677c8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt @@ -2,59 +2,54 @@ package com.vitorpamplona.amethyst.ui.screen import androidx.compose.animation.Crossfade import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.pullrefresh.PullRefreshIndicator +import androidx.compose.material.pullrefresh.pullRefresh +import androidx.compose.material.pullrefresh.rememberPullRefreshState 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.unit.dp import androidx.navigation.NavController -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +@OptIn(ExperimentalMaterialApi::class) @Composable fun UserFeedView(viewModel: UserFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) { val feedState by viewModel.feedContent.collectAsState() - var isRefreshing by remember { mutableStateOf(false) } - val swipeRefreshState = rememberSwipeRefreshState(isRefreshing) + var refreshing by remember { mutableStateOf(false) } + val refresh = { refreshing = true; viewModel.refresh(); refreshing = false } + val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) - LaunchedEffect(isRefreshing) { - if (isRefreshing) { - viewModel.refresh() - isRefreshing = false - } - } - - SwipeRefresh( - state = swipeRefreshState, - onRefresh = { - isRefreshing = true - } - ) { + Box(Modifier.pullRefresh(pullRefreshState)) { Column() { Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is UserFeedState.Empty -> { FeedEmpty { - isRefreshing = true + refreshing = true } } is UserFeedState.FeedError -> { FeedError(state.errorMessage) { - isRefreshing = true + refreshing = true } } is UserFeedState.Loaded -> { + refreshing = false FeedLoaded(state, accountViewModel, navController) } is UserFeedState.Loading -> { @@ -63,6 +58,8 @@ fun UserFeedView(viewModel: UserFeedViewModel, accountViewModel: AccountViewMode } } } + + PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } }