Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add retry button when loading more posts fails #1209

Merged
merged 3 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/src/main/java/com/jerboa/api/Http.kt
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,11 @@ sealed class ApiState<out T> {
abstract class Holder<T>(val data: T) : ApiState<T>()
class Success<T>(data: T) : Holder<T>(data)
class Appending<T>(data: T) : Holder<T>(data)
class AppendingFailure<T>(data: T) : Holder<T>(data)
class Failure(val msg: Throwable) : ApiState<Nothing>()
object Loading : ApiState<Nothing>()
object Refreshing : ApiState<Nothing>()
object Empty : ApiState<Nothing>()
data object Loading : ApiState<Nothing>()
data object Refreshing : ApiState<Nothing>()
data object Empty : ApiState<Nothing>()
}

fun <T> apiWrapper(
Expand Down
10 changes: 4 additions & 6 deletions app/src/main/java/com/jerboa/model/CommunityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ class CommunityViewModel : ViewModel(), Initializable {
fun appendPosts(id: CommunityId, jwt: String?) {
viewModelScope.launch {
val oldRes = postsRes
when (oldRes) {
is ApiState.Success -> postsRes = ApiState.Appending(oldRes.data)
postsRes = when (oldRes) {
is ApiState.Appending -> return@launch
is ApiState.Holder -> ApiState.Appending(oldRes.data)
else -> return@launch
}

Expand All @@ -118,9 +119,6 @@ class CommunityViewModel : ViewModel(), Initializable {

postsRes = when (newRes) {
is ApiState.Success -> {
if (newRes.data.posts.isEmpty()) { // Hit the end of the posts
prevPage()
}
ApiState.Success(
GetPostsResponse(
mergePosts(
Expand All @@ -133,7 +131,7 @@ class CommunityViewModel : ViewModel(), Initializable {

else -> {
prevPage()
oldRes
ApiState.AppendingFailure(oldRes.data)
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions app/src/main/java/com/jerboa/model/HomeViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ class HomeViewModel(private val accountRepository: AccountRepository) : ViewMode
fun appendPosts(jwt: String?) {
viewModelScope.launch {
val oldRes = postsRes
when (oldRes) {
is ApiState.Success -> postsRes = ApiState.Appending(oldRes.data)
postsRes = when (oldRes) {
is ApiState.Appending -> return@launch
is ApiState.Holder -> ApiState.Appending(oldRes.data)
else -> return@launch
}

Expand All @@ -119,9 +120,6 @@ class HomeViewModel(private val accountRepository: AccountRepository) : ViewMode

postsRes = when (newRes) {
is ApiState.Success -> {
if (newRes.data.posts.isEmpty()) { // Hit the end of the posts
prevPage()
}
ApiState.Success(
GetPostsResponse(
mergePosts(
Expand All @@ -134,7 +132,7 @@ class HomeViewModel(private val accountRepository: AccountRepository) : ViewMode

else -> {
prevPage()
oldRes
ApiState.AppendingFailure(oldRes.data)
}
}
}
Expand Down
9 changes: 0 additions & 9 deletions app/src/main/java/com/jerboa/model/InboxViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,6 @@ class InboxViewModel : ViewModel(), Initializable {

repliesRes = when (newRes) {
is ApiState.Success -> {
if (newRes.data.replies.isEmpty()) { // Hit the end of the replies
pageReplies -= 1
}
val appended = oldRes.data.replies.toMutableList()
appended.addAll(newRes.data.replies)
ApiState.Success(oldRes.data.copy(replies = appended))
Expand Down Expand Up @@ -181,9 +178,6 @@ class InboxViewModel : ViewModel(), Initializable {

mentionsRes = when (newRes) {
is ApiState.Success -> {
if (newRes.data.mentions.isEmpty()) { // Hit the end of the replies
pageMentions -= 1
}
val appended = oldRes.data.mentions.toMutableList()
appended.addAll(newRes.data.mentions)
ApiState.Success(oldRes.data.copy(mentions = appended))
Expand Down Expand Up @@ -228,9 +222,6 @@ class InboxViewModel : ViewModel(), Initializable {

messagesRes = when (newRes) {
is ApiState.Success -> {
if (newRes.data.private_messages.isEmpty()) { // Hit the end of the replies
pageMessages -= 1
}
val appended = oldRes.data.private_messages.toMutableList()
appended.addAll(newRes.data.private_messages)
ApiState.Success(oldRes.data.copy(private_messages = appended))
Expand Down
17 changes: 6 additions & 11 deletions app/src/main/java/com/jerboa/model/PersonProfileViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.jerboa.datatypes.types.DeleteComment
import com.jerboa.datatypes.types.DeletePost
import com.jerboa.datatypes.types.GetPersonDetails
import com.jerboa.datatypes.types.GetPersonDetailsResponse
import com.jerboa.datatypes.types.GetPostResponse
import com.jerboa.datatypes.types.MarkPostAsRead
import com.jerboa.datatypes.types.PersonId
import com.jerboa.datatypes.types.PostResponse
Expand All @@ -42,18 +41,13 @@ import kotlinx.coroutines.launch
class PersonProfileViewModel : ViewModel(), Initializable {
override var initialized by mutableStateOf(false)

var personDetailsRes: ApiState<GetPersonDetailsResponse> by mutableStateOf(
ApiState.Empty,
)
var personDetailsRes: ApiState<GetPersonDetailsResponse> by mutableStateOf(ApiState.Empty)
private set

private var postRes: ApiState<GetPostResponse> by mutableStateOf(ApiState.Empty)

private var likePostRes: ApiState<PostResponse> by mutableStateOf(ApiState.Empty)
private var savePostRes: ApiState<PostResponse> by mutableStateOf(ApiState.Empty)
private var deletePostRes: ApiState<PostResponse> by mutableStateOf(ApiState.Empty)
private var blockCommunityRes: ApiState<BlockCommunityResponse> by
mutableStateOf(ApiState.Empty)
private var blockCommunityRes: ApiState<BlockCommunityResponse> by mutableStateOf(ApiState.Empty)
private var blockPersonRes: ApiState<BlockPersonResponse> by mutableStateOf(ApiState.Empty)

private var likeCommentRes: ApiState<CommentResponse> by mutableStateOf(ApiState.Empty)
Expand Down Expand Up @@ -108,8 +102,9 @@ class PersonProfileViewModel : ViewModel(), Initializable {
) {
viewModelScope.launch {
val oldRes = personDetailsRes
when (oldRes) {
is ApiState.Success -> personDetailsRes = ApiState.Appending(oldRes.data)
personDetailsRes = when (oldRes) {
is ApiState.Appending -> return@launch
is ApiState.Holder -> ApiState.Appending(oldRes.data)
else -> return@launch
}

Expand Down Expand Up @@ -141,7 +136,7 @@ class PersonProfileViewModel : ViewModel(), Initializable {

else -> {
prevPage()
oldRes
ApiState.AppendingFailure(oldRes.data)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@ package com.jerboa.ui.components.common

import android.content.Context
import android.widget.Toast
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.jerboa.api.ApiState

@Composable
fun ApiErrorText(
msg: Throwable,
paddingValues: PaddingValues = PaddingValues(),
) {
msg.message?.also { Text(text = it, color = MaterialTheme.colorScheme.error) }
msg.message?.also {
Text(
text = it,
modifier = Modifier.padding(paddingValues),
color = MaterialTheme.colorScheme.error,
)
}
}

fun apiErrorToast(
Expand Down
29 changes: 29 additions & 0 deletions app/src/main/java/com/jerboa/ui/components/common/Buttons.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.jerboa.ui.components.common

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.jerboa.R
import com.jerboa.ui.theme.XXL_PADDING

@Composable
fun RetryLoadingPosts(onClick: () -> Unit) {
Button(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = XXL_PADDING),
onClick = onClick,
colors = ButtonDefaults.buttonColors(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, just to force it as an error color.

containerColor = MaterialTheme.colorScheme.errorContainer,
contentColor = MaterialTheme.colorScheme.onErrorContainer,
),
) {
Text(stringResource(R.string.posts_failed_loading))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ fun CommunityActivity(
onShareClick = { url ->
shareLink(url, ctx)
},
isScrolledToEnd = {
loadMorePosts = {
when (val communityRes = communityViewModel.communityRes) {
is ApiState.Success -> {
communityViewModel.appendPosts(
Expand All @@ -465,9 +465,9 @@ fun CommunityActivity(
padding = padding,
listState = postListState,
postViewMode = getPostViewMode(appSettingsViewModel),
showVotingArrowsInListView = showVotingArrowsInListView,
enableDownVotes = siteViewModel.enableDownvotes(),
showAvatar = siteViewModel.showAvatar(),
showVotingArrowsInListView = showVotingArrowsInListView,
useCustomTabs = useCustomTabs,
usePrivateTabs = usePrivateTabs,
blurNSFW = blurNSFW,
Expand All @@ -489,6 +489,7 @@ fun CommunityActivity(
showIfRead = true,
showScores = siteViewModel.showScores(),
postActionbarMode = postActionbarMode,
showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure,
)
}
else -> {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ fun MainPostListingsContent(
when (val siteRes = siteViewModel.siteRes) {
ApiState.Loading -> LoadingBar(padding)
ApiState.Empty -> ApiEmptyText()
is ApiState.Failure -> ApiErrorText(siteRes.msg)
is ApiState.Failure -> ApiErrorText(siteRes.msg, padding)
is ApiState.Success -> {
taglines = siteRes.data.taglines
}
Expand Down Expand Up @@ -391,13 +391,11 @@ fun MainPostListingsContent(
onCommunityClick = { community ->
appState.toCommunity(id = community.id)
},
onPersonClick = { personId ->
appState.toProfile(id = personId)
},
onPersonClick = appState::toProfile,
onShareClick = { url ->
shareLink(url, ctx)
},
isScrolledToEnd = {
loadMorePosts = {
homeViewModel.appendPosts(account.jwt)
},
account = account,
Expand Down Expand Up @@ -425,6 +423,7 @@ fun MainPostListingsContent(
showIfRead = true,
showScores = siteViewModel.showScores(),
postActionbarMode = postActionbarMode,
showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ fun UserTabs(
onShareClick = { url ->
shareLink(url, ctx)
},
isScrolledToEnd = {
loadMorePosts = {
personProfileViewModel.appendData(
profileRes.data.person_view.person.id,
account.getJWT(),
Expand All @@ -625,14 +625,14 @@ fun UserTabs(
account = account,
listState = postListState,
postViewMode = getPostViewMode(appSettingsViewModel),
showVotingArrowsInListView = showVotingArrowsInListView,
enableDownVotes = enableDownVotes,
showAvatar = showAvatar,
showVotingArrowsInListView = showVotingArrowsInListView,
useCustomTabs = useCustomTabs,
usePrivateTabs = usePrivateTabs,
blurNSFW = blurNSFW,
appState = appState,
showPostLinkPreviews = showPostLinkPreviews,
appState = appState,
markAsReadOnScroll = markAsReadOnScroll,
onMarkAsRead = {
if (!account.isAnon() && !it.read) {
Expand All @@ -649,6 +649,7 @@ fun UserTabs(
showIfRead = false,
showScores = showScores,
postActionbarMode = postActionbarMode,
showPostAppendRetry = personProfileViewModel.personDetailsRes is ApiState.AppendingFailure,
)
}
else -> {}
Expand Down
17 changes: 13 additions & 4 deletions app/src/main/java/com/jerboa/ui/components/post/PostListings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.jerboa.db.entity.Account
import com.jerboa.db.entity.AnonAccount
import com.jerboa.isScrolledToEnd
import com.jerboa.rememberJerboaAppState
import com.jerboa.ui.components.common.RetryLoadingPosts
import com.jerboa.ui.components.common.simpleVerticalScrollbar
import com.jerboa.ui.theme.SMALL_PADDING
import kotlinx.collections.immutable.ImmutableList
Expand All @@ -50,7 +51,7 @@ fun PostListings(
onBlockCommunityClick: (community: Community) -> Unit,
onBlockCreatorClick: (person: Person) -> Unit,
onShareClick: (url: String) -> Unit,
isScrolledToEnd: () -> Unit,
loadMorePosts: () -> Unit,
account: Account,
showCommunityName: Boolean = true,
padding: PaddingValues = PaddingValues(0.dp),
Expand All @@ -69,6 +70,7 @@ fun PostListings(
showIfRead: Boolean,
showScores: Boolean,
postActionbarMode: Int,
showPostAppendRetry: Boolean,
) {
LazyColumn(
state = listState,
Expand Down Expand Up @@ -129,6 +131,12 @@ fun PostListings(
}
Divider(modifier = Modifier.padding(bottom = SMALL_PADDING))
}

if (showPostAppendRetry) {
item(contentType = "retry_posts") {
RetryLoadingPosts(loadMorePosts)
}
}
}

// observer when reached end of list
Expand All @@ -139,9 +147,9 @@ fun PostListings(
}

// Act when end of list reached
if (endOfListReached) {
if (endOfListReached && !showPostAppendRetry) {
LaunchedEffect(Unit) {
isScrolledToEnd()
loadMorePosts()
}
}
}
Expand All @@ -163,7 +171,7 @@ fun PreviewPostListings() {
onBlockCommunityClick = {},
onBlockCreatorClick = {},
onShareClick = {},
isScrolledToEnd = {},
loadMorePosts = {},
account = AnonAccount,
listState = rememberLazyListState(),
postViewMode = PostViewMode.Card,
Expand All @@ -180,5 +188,6 @@ fun PreviewPostListings() {
showIfRead = true,
showScores = true,
postActionbarMode = 0,
showPostAppendRetry = false,
)
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,5 @@
<string name="no_activity_found">No activity (app) found that can open this link</string>
<string name="markdownHelper_insertSpoiler">Insert spoiler</string>
<string name="matrix_send_msg">Connect on Matrix</string>
<string name="posts_failed_loading">Posts failed loading, retry</string>
</resources>