refactor(android): boost page load performance

This is kinda embarassing tbh.
This commit is contained in:
Harsh Shandilya 2024-04-18 17:50:23 +05:30
parent 0ca18d9216
commit ced43b00be
6 changed files with 24 additions and 26 deletions

View File

@ -16,11 +16,13 @@ import dagger.assisted.AssistedInject
import dev.msfjarvis.claw.android.viewmodel.ReadPostsRepository import dev.msfjarvis.claw.android.viewmodel.ReadPostsRepository
import dev.msfjarvis.claw.android.viewmodel.SavedPostsRepository import dev.msfjarvis.claw.android.viewmodel.SavedPostsRepository
import dev.msfjarvis.claw.core.injection.IODispatcher import dev.msfjarvis.claw.core.injection.IODispatcher
import dev.msfjarvis.claw.database.local.SavedPost
import dev.msfjarvis.claw.model.LobstersPost import dev.msfjarvis.claw.model.LobstersPost
import dev.msfjarvis.claw.model.UIPost import dev.msfjarvis.claw.model.UIPost
import dev.msfjarvis.claw.model.toUIPost import dev.msfjarvis.claw.model.toUIPost
import java.io.IOException import java.io.IOException
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class LobstersPagingSource class LobstersPagingSource
@ -31,8 +33,16 @@ constructor(
private val savedPostsRepository: SavedPostsRepository, private val savedPostsRepository: SavedPostsRepository,
private val readPostsRepository: ReadPostsRepository, private val readPostsRepository: ReadPostsRepository,
) : PagingSource<Int, UIPost>() { ) : PagingSource<Int, UIPost>() {
private lateinit var savedPosts: List<String>
private lateinit var readPosts: List<String>
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, UIPost> { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, UIPost> {
if (!::savedPosts.isInitialized) {
savedPosts = savedPostsRepository.savedPosts.first().map(SavedPost::shortId)
}
if (!::readPosts.isInitialized) {
readPosts = readPostsRepository.readPosts.first()
}
val page = params.key ?: STARTING_PAGE_INDEX val page = params.key ?: STARTING_PAGE_INDEX
return when (val result = withContext(ioDispatcher) { remoteFetcher.getItemsAtPage(page) }) { return when (val result = withContext(ioDispatcher) { remoteFetcher.getItemsAtPage(page) }) {
is Success -> is Success ->
@ -43,8 +53,8 @@ constructor(
it it
.toUIPost() .toUIPost()
.copy( .copy(
isSaved = savedPostsRepository.isPostSaved(it.shortId), isSaved = savedPosts.contains(it.shortId),
isRead = readPostsRepository.isPostRead(it.shortId), isRead = readPosts.contains(it.shortId),
) )
}, },
prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1, prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1,

View File

@ -18,10 +18,12 @@ import dev.msfjarvis.claw.android.viewmodel.ReadPostsRepository
import dev.msfjarvis.claw.android.viewmodel.SavedPostsRepository import dev.msfjarvis.claw.android.viewmodel.SavedPostsRepository
import dev.msfjarvis.claw.api.LobstersSearchApi import dev.msfjarvis.claw.api.LobstersSearchApi
import dev.msfjarvis.claw.core.injection.IODispatcher import dev.msfjarvis.claw.core.injection.IODispatcher
import dev.msfjarvis.claw.database.local.SavedPost
import dev.msfjarvis.claw.model.UIPost import dev.msfjarvis.claw.model.UIPost
import dev.msfjarvis.claw.model.toUIPost import dev.msfjarvis.claw.model.toUIPost
import java.io.IOException import java.io.IOException
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
/** /**
@ -39,8 +41,16 @@ constructor(
private val savedPostsRepository: SavedPostsRepository, private val savedPostsRepository: SavedPostsRepository,
private val readPostsRepository: ReadPostsRepository, private val readPostsRepository: ReadPostsRepository,
) : PagingSource<Int, UIPost>() { ) : PagingSource<Int, UIPost>() {
private lateinit var savedPosts: List<String>
private lateinit var readPosts: List<String>
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, UIPost> { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, UIPost> {
if (!::savedPosts.isInitialized) {
savedPosts = savedPostsRepository.savedPosts.first().map(SavedPost::shortId)
}
if (!::readPosts.isInitialized) {
readPosts = readPostsRepository.readPosts.first()
}
val searchQuery = queryProvider() val searchQuery = queryProvider()
// If there is no query, we don't need to call the API at all. // If there is no query, we don't need to call the API at all.
if (searchQuery.isEmpty()) { if (searchQuery.isEmpty()) {
@ -60,8 +70,8 @@ constructor(
it it
.toUIPost() .toUIPost()
.copy( .copy(
isSaved = savedPostsRepository.isPostSaved(it.shortId), isSaved = savedPosts.contains(it.shortId),
isRead = readPostsRepository.isPostRead(it.shortId), isRead = readPosts.contains(it.shortId),
) )
}, },
prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1, prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1,

View File

@ -25,8 +25,4 @@ constructor(
suspend fun markRead(postId: String) { suspend fun markRead(postId: String) {
withContext(dbDispatcher) { readPostsQueries.markRead(postId) } withContext(dbDispatcher) { readPostsQueries.markRead(postId) }
} }
suspend fun isPostRead(shortId: String): Boolean {
return withContext(dbDispatcher) { readPostsQueries.isPostRead(shortId).executeAsOne() }
}
} }

View File

@ -45,10 +45,6 @@ constructor(
} }
} }
suspend fun isPostSaved(postId: String): Boolean {
return withContext(dbDispatcher) { savedPostQueries.isPostSaved(postId).executeAsOne() }
}
private companion object { private companion object {
private const val TAG = "SavedPostsRepository" private const val TAG = "SavedPostsRepository"
} }

View File

@ -2,13 +2,6 @@ CREATE TABLE IF NOT EXISTS ReadPosts(
id TEXT NOT NULL PRIMARY KEY id TEXT NOT NULL PRIMARY KEY
); );
isPostRead:
SELECT EXISTS(
SELECT 1
FROM ReadPosts
WHERE id = ?
) AS isRead;
selectAllPosts: selectAllPosts:
SELECT * SELECT *
FROM ReadPosts; FROM ReadPosts;

View File

@ -14,13 +14,6 @@ CREATE TABLE IF NOT EXISTS SavedPost(
description TEXT NOT NULL DEFAULT "" description TEXT NOT NULL DEFAULT ""
); );
isPostSaved:
SELECT EXISTS(
SELECT 1
FROM SavedPost
WHERE shortId = ?
) AS isSaved;
insertOrReplacePost: insertOrReplacePost:
INSERT OR REPLACE INSERT OR REPLACE
INTO SavedPost INTO SavedPost