mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-06-26 22:00:52 +02:00
Replace deprecated SwipeRefresh with PullRefresh
This commit is contained in:
parent
5da70a0f95
commit
7630e07dc9
@ -2,22 +2,26 @@ package com.vitorpamplona.amethyst.ui.screen
|
|||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
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.BadgeCompose
|
||||||
import com.vitorpamplona.amethyst.ui.note.BoostSetCompose
|
import com.vitorpamplona.amethyst.ui.note.BoostSetCompose
|
||||||
import com.vitorpamplona.amethyst.ui.note.LikeSetCompose
|
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.note.ZapSetCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CardFeedView(viewModel: CardFeedViewModel, accountViewModel: AccountViewModel, navController: NavController, routeForLastRead: String) {
|
fun CardFeedView(viewModel: CardFeedViewModel, accountViewModel: AccountViewModel, navController: NavController, routeForLastRead: String) {
|
||||||
val feedState by viewModel.feedContent.collectAsState()
|
val feedState by viewModel.feedContent.collectAsState()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
if (isRefreshing) {
|
|
||||||
viewModel.refresh()
|
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeRefresh(
|
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
Column() {
|
||||||
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is CardFeedState.Empty -> {
|
is CardFeedState.Empty -> {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CardFeedState.FeedError -> {
|
is CardFeedState.FeedError -> {
|
||||||
FeedError(state.errorMessage) {
|
FeedError(state.errorMessage) {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CardFeedState.Loaded -> {
|
is CardFeedState.Loaded -> {
|
||||||
|
refreshing = false
|
||||||
FeedLoaded(
|
FeedLoaded(
|
||||||
state,
|
state,
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
@ -74,6 +69,8 @@ fun CardFeedView(viewModel: CardFeedViewModel, accountViewModel: AccountViewMode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +62,7 @@ fun ChatroomFeedView(viewModel: FeedViewModel, accountViewModel: AccountViewMode
|
|||||||
reverseLayout = true,
|
reverseLayout = true,
|
||||||
state = listState
|
state = listState
|
||||||
) {
|
) {
|
||||||
var previousDate: String = ""
|
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
||||||
itemsIndexed(state.feed.value, key = { index, item -> item.idHex }) { index, item ->
|
|
||||||
ChatroomMessageCompose(item, routeForLastRead, accountViewModel = accountViewModel, navController = navController, onWantsToReply = onWantsToReply)
|
ChatroomMessageCompose(item, routeForLastRead, accountViewModel = accountViewModel, navController = navController, onWantsToReply = onWantsToReply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,16 @@ package com.vitorpamplona.amethyst.ui.screen
|
|||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
@ -14,18 +19,18 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
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.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.navigation.NavController
|
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.NotificationCache
|
||||||
import com.vitorpamplona.amethyst.ui.note.ChatroomCompose
|
import com.vitorpamplona.amethyst.ui.note.ChatroomCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatroomListFeedView(
|
fun ChatroomListFeedView(
|
||||||
viewModel: FeedViewModel,
|
viewModel: FeedViewModel,
|
||||||
@ -35,24 +40,11 @@ fun ChatroomListFeedView(
|
|||||||
) {
|
) {
|
||||||
val feedState by viewModel.feedContent.collectAsStateWithLifecycle()
|
val feedState by viewModel.feedContent.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
|
||||||
if (isRefreshing) {
|
|
||||||
viewModel.refresh()
|
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeRefresh(
|
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
Column() {
|
||||||
Crossfade(
|
Crossfade(
|
||||||
targetState = feedState,
|
targetState = feedState,
|
||||||
@ -61,17 +53,18 @@ fun ChatroomListFeedView(
|
|||||||
when (state) {
|
when (state) {
|
||||||
is FeedState.Empty -> {
|
is FeedState.Empty -> {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is FeedState.FeedError -> {
|
is FeedState.FeedError -> {
|
||||||
FeedError(state.errorMessage) {
|
FeedError(state.errorMessage) {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is FeedState.Loaded -> {
|
is FeedState.Loaded -> {
|
||||||
|
refreshing = false
|
||||||
FeedLoaded(state, accountViewModel, navController, markAsRead)
|
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) {
|
if (markAsRead.value) {
|
||||||
for (note in state.feed.value) {
|
for (note in state.feed.value) {
|
||||||
note.event?.let {
|
note.event?.let {
|
||||||
var route = ""
|
|
||||||
val channel = note.channel()
|
val channel = note.channel()
|
||||||
|
val route = if (channel != null) {
|
||||||
if (channel != null) {
|
"Channel/${channel.idHex}"
|
||||||
route = "Channel/${channel.idHex}"
|
|
||||||
} else {
|
} else {
|
||||||
val replyAuthorBase = note.mentions?.first()
|
val replyAuthorBase = note.mentions?.first()
|
||||||
var userToComposeOn = note.author!!
|
var userToComposeOn = note.author!!
|
||||||
@ -116,7 +109,7 @@ private fun FeedLoaded(
|
|||||||
userToComposeOn = replyAuthorBase
|
userToComposeOn = replyAuthorBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
route = "Room/${userToComposeOn.pubkeyHex}"
|
"Room/${userToComposeOn.pubkeyHex}"
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationCache.cache.markAsRead(route, it.createdAt(), context)
|
notificationCache.cache.markAsRead(route, it.createdAt(), context)
|
||||||
@ -136,7 +129,7 @@ private fun FeedLoaded(
|
|||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
state.feed.value,
|
state.feed.value,
|
||||||
key = { index, item -> if (index == 0) index else item.idHex }
|
key = { index, item -> if (index == 0) index else item.idHex }
|
||||||
) { index, item ->
|
) { _, item ->
|
||||||
ChatroomCompose(
|
ChatroomCompose(
|
||||||
item,
|
item,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
|
@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.screen
|
|||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
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.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.Button
|
import androidx.compose.material.Button
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.OutlinedButton
|
import androidx.compose.material.OutlinedButton
|
||||||
import androidx.compose.material.Text
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -25,12 +29,11 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
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.R
|
||||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun FeedView(
|
fun FeedView(
|
||||||
viewModel: FeedViewModel,
|
viewModel: FeedViewModel,
|
||||||
@ -41,36 +44,31 @@ fun FeedView(
|
|||||||
) {
|
) {
|
||||||
val feedState by viewModel.feedContent.collectAsState()
|
val feedState by viewModel.feedContent.collectAsState()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
if (isRefreshing) {
|
Column {
|
||||||
viewModel.refresh()
|
Crossfade(
|
||||||
isRefreshing = false
|
targetState = feedState,
|
||||||
}
|
animationSpec = tween(durationMillis = 100)
|
||||||
}
|
) { state ->
|
||||||
|
|
||||||
SwipeRefresh(
|
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
|
||||||
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
|
||||||
when (state) {
|
when (state) {
|
||||||
is FeedState.Empty -> {
|
is FeedState.Empty -> {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is FeedState.FeedError -> {
|
is FeedState.FeedError -> {
|
||||||
FeedError(state.errorMessage) {
|
FeedError(state.errorMessage) {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is FeedState.Loaded -> {
|
is FeedState.Loaded -> {
|
||||||
|
refreshing = false
|
||||||
FeedLoaded(
|
FeedLoaded(
|
||||||
state,
|
state,
|
||||||
routeForLastRead,
|
routeForLastRead,
|
||||||
@ -79,12 +77,15 @@ fun FeedView(
|
|||||||
scrollStateKey
|
scrollStateKey
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is FeedState.Loading -> {
|
is FeedState.Loading -> {
|
||||||
LoadingFeed()
|
LoadingFeed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ private fun FeedLoaded(
|
|||||||
),
|
),
|
||||||
state = listState
|
state = listState
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { index, item ->
|
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
||||||
NoteCompose(
|
NoteCompose(
|
||||||
item,
|
item,
|
||||||
isBoostedNote = false,
|
isBoostedNote = false,
|
||||||
|
@ -2,59 +2,54 @@ package com.vitorpamplona.amethyst.ui.screen
|
|||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
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.note.ZapNoteCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun LnZapFeedView(viewModel: LnZapFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
fun LnZapFeedView(viewModel: LnZapFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
val feedState by viewModel.feedContent.collectAsState()
|
val feedState by viewModel.feedContent.collectAsState()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
if (isRefreshing) {
|
|
||||||
viewModel.refresh()
|
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeRefresh(
|
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
Column() {
|
||||||
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is LnZapFeedState.Empty -> {
|
is LnZapFeedState.Empty -> {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is LnZapFeedState.FeedError -> {
|
is LnZapFeedState.FeedError -> {
|
||||||
FeedError(state.errorMessage) {
|
FeedError(state.errorMessage) {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is LnZapFeedState.Loaded -> {
|
is LnZapFeedState.Loaded -> {
|
||||||
|
refreshing = false
|
||||||
LnZapFeedLoaded(state, accountViewModel, navController)
|
LnZapFeedLoaded(state, accountViewModel, navController)
|
||||||
}
|
}
|
||||||
is LnZapFeedState.Loading -> {
|
is LnZapFeedState.Loading -> {
|
||||||
@ -63,6 +58,8 @@ fun LnZapFeedView(viewModel: LnZapFeedViewModel, accountViewModel: AccountViewMo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen
|
package com.vitorpamplona.amethyst.ui.screen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavController
|
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.RelayInfo
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.model.UserState
|
import com.vitorpamplona.amethyst.model.UserState
|
||||||
@ -101,6 +105,7 @@ class RelayFeedViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
@ -108,9 +113,6 @@ fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewMo
|
|||||||
|
|
||||||
val feedState by viewModel.feedContent.collectAsState()
|
val feedState by viewModel.feedContent.collectAsState()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
|
||||||
|
|
||||||
var wantsToAddRelay by remember {
|
var wantsToAddRelay by remember {
|
||||||
mutableStateOf("")
|
mutableStateOf("")
|
||||||
}
|
}
|
||||||
@ -119,19 +121,11 @@ fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewMo
|
|||||||
NewRelayListView({ wantsToAddRelay = "" }, account, wantsToAddRelay)
|
NewRelayListView({ wantsToAddRelay = "" }, account, wantsToAddRelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
if (isRefreshing) {
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
viewModel.refresh()
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeRefresh(
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
Column() {
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
@ -153,5 +147,7 @@ fun RelayFeedView(viewModel: RelayFeedViewModel, accountViewModel: AccountViewMo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import androidx.compose.animation.core.tween
|
|||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
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.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.Divider
|
import androidx.compose.material.Divider
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@ -44,8 +49,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
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.R
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.service.model.BadgeDefinitionEvent
|
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 com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
val feedState by viewModel.feedContent.collectAsState()
|
val feedState by viewModel.feedContent.collectAsState()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
|
||||||
|
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
if (isRefreshing) {
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
viewModel.refresh()
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeRefresh(
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
Column() {
|
||||||
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is FeedState.Empty -> {
|
is FeedState.Empty -> {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FeedState.FeedError -> {
|
is FeedState.FeedError -> {
|
||||||
FeedError(state.errorMessage) {
|
FeedError(state.errorMessage) {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FeedState.Loaded -> {
|
is FeedState.Loaded -> {
|
||||||
|
refreshing = false
|
||||||
LaunchedEffect(noteId) {
|
LaunchedEffect(noteId) {
|
||||||
// waits to load the thread to scroll to item.
|
// waits to load the thread to scroll to item.
|
||||||
delay(100)
|
delay(100)
|
||||||
@ -163,6 +157,8 @@ fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: A
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,59 +2,54 @@ package com.vitorpamplona.amethyst.ui.screen
|
|||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
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.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
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.note.UserCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserFeedView(viewModel: UserFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
fun UserFeedView(viewModel: UserFeedViewModel, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
val feedState by viewModel.feedContent.collectAsState()
|
val feedState by viewModel.feedContent.collectAsState()
|
||||||
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var refreshing by remember { mutableStateOf(false) }
|
||||||
val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)
|
val refresh = { refreshing = true; viewModel.refresh(); refreshing = false }
|
||||||
|
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
|
||||||
|
|
||||||
LaunchedEffect(isRefreshing) {
|
Box(Modifier.pullRefresh(pullRefreshState)) {
|
||||||
if (isRefreshing) {
|
|
||||||
viewModel.refresh()
|
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeRefresh(
|
|
||||||
state = swipeRefreshState,
|
|
||||||
onRefresh = {
|
|
||||||
isRefreshing = true
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Column() {
|
Column() {
|
||||||
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
Crossfade(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is UserFeedState.Empty -> {
|
is UserFeedState.Empty -> {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is UserFeedState.FeedError -> {
|
is UserFeedState.FeedError -> {
|
||||||
FeedError(state.errorMessage) {
|
FeedError(state.errorMessage) {
|
||||||
isRefreshing = true
|
refreshing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is UserFeedState.Loaded -> {
|
is UserFeedState.Loaded -> {
|
||||||
|
refreshing = false
|
||||||
FeedLoaded(state, accountViewModel, navController)
|
FeedLoaded(state, accountViewModel, navController)
|
||||||
}
|
}
|
||||||
is UserFeedState.Loading -> {
|
is UserFeedState.Loading -> {
|
||||||
@ -63,6 +58,8 @@ fun UserFeedView(viewModel: UserFeedViewModel, accountViewModel: AccountViewMode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user