Skip to content

Commit

Permalink
Fix Posts failed loading, retry (#1302)
Browse files Browse the repository at this point in the history
* Bump lemmyApi and refactor PostsViewModel Code

* Should fix lemmyApi

* Bump lemmyAPI

* Fix ru positional substitutions

* Fix lint
  • Loading branch information
MV-GH authored Dec 18, 2023
1 parent 14f081f commit 4bb41c4
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 407 deletions.
21 changes: 9 additions & 12 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ android {

dependencies {
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.github.alorma:compose-settings-ui-m3:1.0.2")
implementation("com.github.alorma:compose-settings-ui-m3:1.0.3")

implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11")
implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.12")

// Markdown support
implementation("io.noties.markwon:core:4.6.2")
Expand Down Expand Up @@ -152,16 +152,13 @@ dependencies {
testImplementation("pl.pragmatists:JUnitParams:1.1.1")
androidTestImplementation("androidx.room:room-testing:2.6.1")

// optional - Paging 3 Integration
implementation("androidx.room:room-paging:2.6.1")

implementation("io.arrow-kt:arrow-core:1.2.1")
// Unfortunately, ui tooling, and the markdown thing, still brings in the other material2 dependencies
implementation("androidx.compose.material3:material3:1.1.2")
implementation("androidx.compose.material3:material3-window-size-class:1.1.2")

implementation("org.ocpsoft.prettytime:prettytime:5.0.7.Final")
implementation("androidx.navigation:navigation-compose:2.7.5")
implementation("androidx.navigation:navigation-compose:2.7.6")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
testImplementation("androidx.arch.core:core-testing:2.2.0")

Expand All @@ -172,23 +169,23 @@ dependencies {
debugImplementation("androidx.compose.ui:ui-test-manifest:1.5.4")
implementation("androidx.compose.material:material-icons-extended:1.5.4")

implementation("androidx.activity:activity-compose:1.8.1")
implementation("androidx.activity:activity-compose:1.8.2")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

testImplementation("org.mockito:mockito-core:5.7.0")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.1.0")
testImplementation("org.mockito:mockito-core:5.8.0")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")

implementation("androidx.browser:browser:1.7.0")

implementation("androidx.profileinstaller:profileinstaller:1.3.1")
baselineProfile(project(":benchmarks"))

implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.6")
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7")

implementation("it.vercruysse.lemmyapi:lemmy-api:0.2.0-SNAPSHOT")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1")
implementation("it.vercruysse.lemmyapi:lemmy-api:0.2.2-SNAPSHOT")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
// Ktor uses SLF4J
implementation("org.slf4j:slf4j-api:2.0.9")
implementation("uk.uuid.slf4j:slf4j-android:2.0.9-0")
Expand Down
193 changes: 4 additions & 189 deletions app/src/main/java/com/jerboa/model/CommunityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,154 +2,43 @@ package com.jerboa.model

import android.content.Context
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import arrow.core.Either
import com.jerboa.JerboaAppState
import com.jerboa.api.API
import com.jerboa.api.ApiState
import com.jerboa.api.toApiState
import com.jerboa.findAndUpdatePost
import com.jerboa.mergePosts
import com.jerboa.showBlockCommunityToast
import it.vercruysse.lemmyapi.dto.SortType
import it.vercruysse.lemmyapi.v0x19.datatypes.BlockCommunity
import it.vercruysse.lemmyapi.v0x19.datatypes.BlockCommunityResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.CommunityId
import it.vercruysse.lemmyapi.v0x19.datatypes.CommunityResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.CreatePostLike
import it.vercruysse.lemmyapi.v0x19.datatypes.DeletePost
import it.vercruysse.lemmyapi.v0x19.datatypes.FollowCommunity
import it.vercruysse.lemmyapi.v0x19.datatypes.GetCommunity
import it.vercruysse.lemmyapi.v0x19.datatypes.GetCommunityResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.GetPosts
import it.vercruysse.lemmyapi.v0x19.datatypes.GetPostsResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.MarkPostAsRead
import it.vercruysse.lemmyapi.v0x19.datatypes.PaginationCursor
import it.vercruysse.lemmyapi.v0x19.datatypes.PostResponse
import it.vercruysse.lemmyapi.v0x19.datatypes.PostView
import it.vercruysse.lemmyapi.v0x19.datatypes.SavePost
import kotlinx.coroutines.launch

class CommunityViewModel(communityArg: Either<CommunityId, String>) : ViewModel() {
class CommunityViewModel(communityArg: Either<CommunityId, String>) : PostsViewModel() {
var communityRes: ApiState<GetCommunityResponse> by mutableStateOf(ApiState.Empty)
private set

private var followCommunityRes: ApiState<CommunityResponse> by
mutableStateOf(ApiState.Empty)

var postsRes: ApiState<GetPostsResponse> by mutableStateOf(ApiState.Empty)
private set

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 markPostRes: ApiState<Unit> by mutableStateOf(ApiState.Empty)

var sortType by mutableStateOf(SortType.Active)
private set

private var page by mutableIntStateOf(1)
private var pageCursor: PaginationCursor? by mutableStateOf(null)

private var followCommunityRes: ApiState<CommunityResponse> by mutableStateOf(ApiState.Empty)
private var blockCommunityRes: ApiState<BlockCommunityResponse> by mutableStateOf(ApiState.Empty)
private var communityId: Int? by mutableStateOf(null)
private var communityName: String? by mutableStateOf(null)

fun updateSortType(sortType: SortType) {
this.sortType = sortType
}

private fun resetPage() {
page = 1
pageCursor = null
}

private fun nextPage() {
page += 1
}

private fun prevPage() {
page -= 1
}

private fun getCommunity(form: GetCommunity) {
viewModelScope.launch {
communityRes = ApiState.Loading
communityRes = API.getInstance().getCommunity(form).toApiState()
}
}

private fun getPosts(
form: GetPosts,
state: ApiState<GetPostsResponse> = ApiState.Loading,
) {
viewModelScope.launch {
postsRes = state
postsRes = API.getInstance().getPosts(form).toApiState()
}
}

fun appendPosts() {
viewModelScope.launch {
val oldRes = postsRes
postsRes =
when (oldRes) {
is ApiState.Appending -> return@launch
is ApiState.Holder -> ApiState.Appending(oldRes.data)
else -> return@launch
}

// Update the page cursor before fetching again
pageCursor = oldRes.data.next_page
nextPage()

val newRes = API.getInstance().getPosts(getForm()).toApiState()

postsRes =
when (newRes) {
is ApiState.Success -> {
ApiState.Success(
GetPostsResponse(
posts =
mergePosts(
oldRes.data.posts,
newRes.data.posts,
),
next_page = newRes.data.next_page,
),
)
}

else -> {
prevPage()
ApiState.AppendingFailure(oldRes.data)
}
}
}
}

fun resetPosts() {
resetPage()
getPosts(
getForm(),
)
}

fun refreshPosts() {
resetPage()
getPosts(
getForm(),
ApiState.Refreshing,
)
}

fun followCommunity(
form: FollowCommunity,
onSuccess: () -> Unit = {},
Expand Down Expand Up @@ -178,49 +67,6 @@ class CommunityViewModel(communityArg: Either<CommunityId, String>) : ViewModel(
}
}

fun likePost(form: CreatePostLike) {
viewModelScope.launch {
likePostRes = ApiState.Loading
likePostRes = API.getInstance().createPostLike(form).toApiState()

when (val likeRes = likePostRes) {
is ApiState.Success -> {
updatePost(likeRes.data.post_view)
}

else -> {}
}
}
}

fun savePost(form: SavePost) {
viewModelScope.launch {
savePostRes = ApiState.Loading
savePostRes = API.getInstance().savePost(form).toApiState()
when (val saveRes = savePostRes) {
is ApiState.Success -> {
updatePost(saveRes.data.post_view)
}

else -> {}
}
}
}

fun deletePost(form: DeletePost) {
viewModelScope.launch {
deletePostRes = ApiState.Loading
deletePostRes = API.getInstance().deletePost(form).toApiState()
when (val deletePost = deletePostRes) {
is ApiState.Success -> {
updatePost(deletePost.data.post_view)
}

else -> {}
}
}
}

fun blockCommunity(
form: BlockCommunity,
ctx: Context,
Expand Down Expand Up @@ -254,37 +100,6 @@ class CommunityViewModel(communityArg: Either<CommunityId, String>) : ViewModel(
}
}

fun updatePost(postView: PostView) {
when (val existing = postsRes) {
is ApiState.Success -> {
val newPosts = findAndUpdatePost(existing.data.posts, postView)
val newRes = ApiState.Success(existing.data.copy(posts = newPosts))
postsRes = newRes
}

else -> {}
}
}

fun markPostAsRead(
form: MarkPostAsRead,
post: PostView,
appState: JerboaAppState,
) {
appState.coroutineScope.launch {
markPostRes = ApiState.Loading
markPostRes = API.getInstance().markPostAsRead(form).toApiState()

when (markPostRes) {
is ApiState.Success -> {
updatePost(post.copy(read = form.read))
}

else -> {}
}
}
}

init {
communityId = communityArg.fold({ it }, { null })
communityName = communityArg.fold({ null }, { it })
Expand All @@ -303,7 +118,7 @@ class CommunityViewModel(communityArg: Either<CommunityId, String>) : ViewModel(
)
}

private fun getForm(): GetPosts {
override fun getForm(): GetPosts {
return GetPosts(
community_id = communityId,
community_name = communityName,
Expand Down
Loading

0 comments on commit 4bb41c4

Please sign in to comment.