Skip to content

Commit

Permalink
Performance refactors for Posts feed (LemmyNet#1527)
Browse files Browse the repository at this point in the history
* Current WIP

* PostsViewModel Changes

* Fix linter

* Fix linter

* Fix collapsible header causing recompositions

* Do not show empty on startup

* Fix linter

* Apply remarks

* Fix master

* Rebase main

* Fix linter

* Fix OoB case

* Rebase main
  • Loading branch information
MV-GH authored Jun 1, 2024
1 parent 17e2343 commit 461f264
Show file tree
Hide file tree
Showing 20 changed files with 503 additions and 397 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ android {
useSupportLibrary = true
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
arg("room.schemaLocation", "$projectDir/schemas")
}
}

Expand Down
9 changes: 8 additions & 1 deletion app/src/main/java/com/jerboa/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,14 @@ fun getCommentIdDepthFromPath(
}

fun nsfwCheck(postView: PostView): Boolean {
return postView.post.nsfw || postView.community.nsfw
return nsfwCheck(postView.post, postView.community)
}

fun nsfwCheck(
post: Post,
community: Community,
): Boolean {
return post.nsfw || community.nsfw
}

@RequiresApi(Build.VERSION_CODES.Q)
Expand Down
56 changes: 28 additions & 28 deletions app/src/main/java/com/jerboa/datatypes/SampleData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ val samplePost =
community_id = 14681,
removed = false,
locked = false,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
updated = null,
deleted = false,
nsfw = false,
Expand All @@ -74,7 +74,7 @@ val sampleLinkPost =
community_id = 14681,
removed = false,
locked = true,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
updated = null,
deleted = false,
nsfw = false,
Expand All @@ -99,7 +99,7 @@ val sampleLinkNoThumbnailPost =
community_id = 14681,
removed = false,
locked = false,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
updated = null,
deleted = false,
nsfw = false,
Expand All @@ -124,7 +124,7 @@ val sampleImagePost =
community_id = 14681,
removed = false,
locked = false,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
updated = null,
deleted = false,
nsfw = false,
Expand All @@ -149,7 +149,7 @@ val sampleMarkdownPost =
community_id = 14681,
removed = false,
locked = false,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
updated = null,
deleted = false,
nsfw = false,
Expand All @@ -171,8 +171,8 @@ val samplePerson =
display_name = "No longer Homeless",
avatar = "https://lemmy.ml/pictrs/image/LqURxPzFNW.jpg",
banned = false,
published = "2021-08-08T01:47:44.437708",
updated = "2021-10-11T07:14:53.548707",
published = "2021-08-08T01:47:44.437708Z",
updated = "2021-10-11T07:14:53.548707Z",
actor_id = "https://lemmy.ml/u/homeless",
bio =
"This is my bio.\n\nI like trucks, trains, and geese. This is *one* longer line " +
Expand All @@ -194,8 +194,8 @@ val samplePerson2 =
display_name = null,
avatar = "https://lemmy.ml/pictrs/image/kykidJ1ssM.jpg",
banned = false,
published = "2021-08-08T01:47:44.437708",
updated = "2021-10-11T07:14:53.548707",
published = "2021-08-08T01:47:44.437708Z",
updated = "2021-10-11T07:14:53.548707Z",
actor_id = "https://lemmy.ml/u/homeless",
bio = null,
local = false,
Expand All @@ -213,8 +213,8 @@ val samplePerson3 =
name = "witch_power",
display_name = null,
banned = false,
published = "2021-08-08T01:47:44.437708",
updated = "2021-10-11T07:14:53.548707",
published = "2021-08-08T01:47:44.437708Z",
updated = "2021-10-11T07:14:53.548707Z",
actor_id = "https://lemmy.ml/u/witch_power",
bio = null,
local = true,
Expand Down Expand Up @@ -260,8 +260,8 @@ val sampleCommunity =
title = "Socialism",
description = "This is the r/socialism community",
removed = false,
published = "2019-04-30T13:28:35.965035",
updated = "2021-01-25T16:27:15.804739",
published = "2019-04-30T13:28:35.965035Z",
updated = "2021-01-25T16:27:15.804739Z",
deleted = false,
nsfw = false,
actor_id = "https://lemmy.ml/c/socialism",
Expand All @@ -282,7 +282,7 @@ val samplePostAggregates =
score = 8,
upvotes = 8,
downvotes = 0,
published = "2022-01-02T04:02:44.592929",
published = "2022-01-02T04:02:44.592929Z",
)

val samplePostView =
Expand Down Expand Up @@ -381,8 +381,8 @@ val sampleComment =
"work" +
".\n\nIts kind of a long comment\n\nbut I don't want...",
removed = false,
published = "2022-01-07T03:12:26.398434",
updated = "2022-01-07T03:15:37.360888",
published = "2022-01-07T03:12:26.398434Z",
updated = "2022-01-07T03:15:37.360888Z",
deleted = false,
ap_id = "https://midwest.social/comment/24621",
local = false,
Expand All @@ -399,8 +399,8 @@ val sampleReplyComment =
path = "0.1.2",
content = "This is a reply comment.\n\n# This is a header\n\n- list one\n\n- list two",
removed = false,
published = "2022-01-07T04:12:26.398434",
updated = "2022-01-07T03:15:37.360888",
published = "2022-01-07T04:12:26.398434Z",
updated = "2022-01-07T03:15:37.360888Z",
deleted = false,
ap_id = "https://midwest.social/comment/24622",
local = false,
Expand All @@ -416,8 +416,8 @@ val sampleSecondReplyComment =
path = "0.1.2.3",
content = "This is a sub-reply comment, mmmmk",
removed = false,
published = "2022-01-07T04:12:26.398434",
updated = "2022-01-07T03:15:37.360888",
published = "2022-01-07T04:12:26.398434Z",
updated = "2022-01-07T03:15:37.360888Z",
deleted = false,
ap_id = "https://midwest.social/comment/24622",
local = false,
Expand All @@ -431,7 +431,7 @@ val sampleCommentAggregates =
score = 8,
upvotes = 12,
downvotes = 4,
published = "2022-01-02T04:02:44.592929",
published = "2022-01-02T04:02:44.592929Z",
child_count = 0,
)

Expand Down Expand Up @@ -486,7 +486,7 @@ val sampleCommentReply =
recipient_id = 20,
comment_id = 42,
read = false,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
)

val samplePersonMention =
Expand All @@ -495,7 +495,7 @@ val samplePersonMention =
recipient_id = 20,
comment_id = 42,
read = false,
published = "2022-01-01T09:53:46.904077",
published = "2022-01-01T09:53:46.904077Z",
)

val sampleCommentReplyView =
Expand Down Expand Up @@ -534,7 +534,7 @@ val samplePersonMentionView =

val sampleCommunityAggregates =
CommunityAggregates(
published = "2022-01-02T04:02:44.592929",
published = "2022-01-02T04:02:44.592929Z",
community_id = 834,
subscribers = 52,
subscribers_local = 21,
Expand Down Expand Up @@ -576,8 +576,8 @@ val samplePrivateMessage =
content = "A message from *me* to **you**",
deleted = false,
read = false,
published = "2022-01-07T04:12:26.398434",
updated = "2022-01-07T03:15:37.360888",
published = "2022-01-07T04:12:26.398434Z",
updated = "2022-01-07T03:15:37.360888Z",
ap_id = "https://midwest.social/comment/24622",
local = false,
)
Expand All @@ -595,8 +595,8 @@ val sampleSite =
name = "Lemmy.ml",
sidebar = "# Hello!\n\n**This is** lemmy's sidebar",
description = "A general purpose instance for lemmy",
published = "2022-01-07T04:12:26.398434",
updated = "2022-01-07T03:15:37.360888",
published = "2022-01-07T04:12:26.398434Z",
updated = "2022-01-07T03:15:37.360888Z",
icon = "https://lemmy.ml/pictrs/image/LqURxPzFNW.jpg",
banner = "https://lemmy.ml/pictrs/image/386rk5OYWS.jpg",
actor_id = "https://lemmy.ml",
Expand Down
74 changes: 74 additions & 0 deletions app/src/main/java/com/jerboa/feed/FeedController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.jerboa.feed

import android.util.Log
import androidx.compose.runtime.mutableStateListOf

open class FeedController<T> {
protected val items = mutableStateListOf<T>()

val feed: List<T> = items

fun updateAll(
selector: (List<T>) -> List<Int>,
transformer: (T) -> T,
) {
selector(items).forEach {
safeUpdate(it, transformer)
}
}

fun safeUpdate(
index: Int,
transformer: (T) -> T,
) {
if (!isValidIndex(index)) {
Log.d("FeedController", "OoB item not updated $index")
return
}

safeUpdate(index, transformer(items[index]))
}

fun safeUpdate(
selector: (List<T>) -> Int,
transformer: (T) -> T,
) {
safeUpdate(selector(items), transformer)
}

/**
* Update the item at the given index with the new item.
*
* If given -1 or an index that is out of bounds, the update will not be performed.
* It assumes that the item couldn't be found because the list has changed.
* Example: a network request to update an item succeeded after the list has changed.
* So, we ignore it
*/
fun safeUpdate(
index: Int,
new: T,
) {
if (isValidIndex(index)) {
items[index] = new
} else {
Log.d("FeedController", "OoB item not updated $new")
}
}

fun add(item: T) = items.add(item)

fun remove(item: T) = items.remove(item)

fun clear() = items.clear()

fun addAll(newItems: List<T>) = items.addAll(newItems)

protected inline fun <E> Iterable<E>.indexesOf(predicate: (E) -> Boolean) =
mapIndexedNotNull { index, elem ->
index.takeIf {
predicate(elem)
}
}

private fun isValidIndex(index: Int) = index >= 0 && index < items.size
}
18 changes: 18 additions & 0 deletions app/src/main/java/com/jerboa/feed/PaginationController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.jerboa.feed

import it.vercruysse.lemmyapi.v0x19.datatypes.PaginationCursor

class PaginationController(
var page: Long = 1,
var pageCursor: PaginationCursor? = null,
) {
fun reset() {
page = 1
pageCursor = null
}

fun nextPage(pageCursor: PaginationCursor?) {
page++
this.pageCursor = pageCursor
}
}
42 changes: 42 additions & 0 deletions app/src/main/java/com/jerboa/feed/PostController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.jerboa.feed

import com.jerboa.datatypes.BanFromCommunityData
import it.vercruysse.lemmyapi.v0x19.datatypes.HidePost
import it.vercruysse.lemmyapi.v0x19.datatypes.Person
import it.vercruysse.lemmyapi.v0x19.datatypes.PostView

open class PostController : FeedController<PostView>() {
fun findAndUpdatePost(updatedPostView: PostView) {
safeUpdate({ posts ->
posts.indexOfFirst {
it.post.id == updatedPostView.post.id
}
}) { updatedPostView }
}

fun findAndUpdateCreator(person: Person) {
updateAll(
{ it.indexesOf { postView -> postView.creator.id == person.id } },
) { it.copy(creator = person) }
}

fun findAndUpdatePostCreatorBannedFromCommunity(banData: BanFromCommunityData) {
updateAll(
{
it.indexesOf { postView ->
postView.creator.id == banData.person.id && postView.community.id == banData.community.id
}
},
) { it.copy(banned_from_community = banData.banned, creator_banned_from_community = banData.banned, creator = banData.person) }
}

fun findAndUpdatePostHidden(hidePost: HidePost) {
updateAll(
{
it.indexesOf { postView ->
hidePost.post_ids.contains(postView.post.id)
}
},
) { it.copy(hidden = hidePost.hide) }
}
}
3 changes: 0 additions & 3 deletions app/src/main/java/com/jerboa/model/HomeViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package com.jerboa.model

import androidx.compose.foundation.lazy.LazyListState
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.jerboa.db.repository.AccountRepository
import com.jerboa.jerboaApplication

class HomeViewModel(accountRepository: AccountRepository) : PostsViewModel(accountRepository) {
val lazyListState = LazyListState()

init {
init()
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/jerboa/model/PostViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ import it.vercruysse.lemmyapi.v0x19.datatypes.SaveComment
import it.vercruysse.lemmyapi.v0x19.datatypes.SavePost
import kotlinx.coroutines.launch

const val COMMENTS_DEPTH_MAX = 6L

class PostViewModel(val id: Either<PostId, CommentId>) : ViewModel() {
var postRes: ApiState<GetPostResponse> by mutableStateOf(ApiState.Empty)
private set
Expand Down Expand Up @@ -442,5 +440,7 @@ class PostViewModel(val id: Either<PostId, CommentId>) : ViewModel() {
return PostViewModel(id) as T
}
}

const val COMMENTS_DEPTH_MAX = 6L
}
}
Loading

0 comments on commit 461f264

Please sign in to comment.