HistoryScreen: Remove paging (#8125)

* HistoryScreen: Remove paging

Per my testing performance-wise there's virtually no
difference in loading time.

* cleanups

* add key and contentType
This commit is contained in:
Ivan Iskandar 2022-10-01 21:50:25 +07:00 committed by GitHub
parent 8d1f99a480
commit 42b0e3e438
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 52 additions and 160 deletions

View file

@ -1,6 +1,5 @@
package eu.kanade.data.history
import androidx.paging.PagingSource
import eu.kanade.data.DatabaseHandler
import eu.kanade.data.chapter.chapterMapper
import eu.kanade.data.manga.mangaMapper
@ -10,19 +9,17 @@ import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.domain.history.repository.HistoryRepository
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
class HistoryRepositoryImpl(
private val handler: DatabaseHandler,
) : HistoryRepository {
override fun getHistory(query: String): PagingSource<Long, HistoryWithRelations> {
return handler.subscribeToPagingSource(
countQuery = { historyViewQueries.countHistory(query) },
queryProvider = { limit, offset ->
historyViewQueries.history(query, limit, offset, historyWithRelationsMapper)
},
)
override fun getHistory(query: String): Flow<List<HistoryWithRelations>> {
return handler.subscribeToList {
historyViewQueries.history(query, historyWithRelationsMapper)
}
}
override suspend fun getLastHistory(): HistoryWithRelations? {

View file

@ -1,8 +1,5 @@
package eu.kanade.domain.history.interactor
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.domain.history.repository.HistoryRepository
import kotlinx.coroutines.flow.Flow
@ -10,12 +7,7 @@ import kotlinx.coroutines.flow.Flow
class GetHistory(
private val repository: HistoryRepository,
) {
fun subscribe(query: String): Flow<PagingData<HistoryWithRelations>> {
return Pager(
PagingConfig(pageSize = 25),
) {
repository.getHistory(query)
}.flow
fun subscribe(query: String): Flow<List<HistoryWithRelations>> {
return repository.getHistory(query)
}
}

View file

@ -1,13 +1,13 @@
package eu.kanade.domain.history.repository
import androidx.paging.PagingSource
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.history.model.HistoryUpdate
import eu.kanade.domain.history.model.HistoryWithRelations
import kotlinx.coroutines.flow.Flow
interface HistoryRepository {
fun getHistory(query: String): PagingSource<Long, HistoryWithRelations>
fun getHistory(query: String): Flow<List<HistoryWithRelations>>
suspend fun getLastHistory(): HistoryWithRelations?

View file

@ -2,8 +2,9 @@ package eu.kanade.presentation.history
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.paging.LoadState
import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen
@ -39,20 +40,25 @@ fun HistoryScreen(
)
},
) { contentPadding ->
val items = presenter.getLazyHistory()
when {
items.loadState.refresh is LoadState.Loading && items.itemCount < 1 -> LoadingScreen()
items.loadState.refresh is LoadState.NotLoading && items.itemCount < 1 -> EmptyScreen(textResource = R.string.information_no_recent_manga)
else -> HistoryContent(
history = items,
val items by presenter.getHistory().collectAsState(initial = null)
items.let {
if (it == null) {
LoadingScreen()
} else if (it.isEmpty()) {
EmptyScreen(textResource = R.string.information_no_recent_manga)
} else {
HistoryContent(
history = it,
contentPadding = contentPadding,
onClickCover = onClickCover,
onClickResume = onClickResume,
onClickDelete = { presenter.dialog = Dialog.Delete(it) },
onClickDelete = { item -> presenter.dialog = Dialog.Delete(item) },
)
}
LaunchedEffect(items.loadState.refresh) {
if (items.loadState.refresh is LoadState.NotLoading) {
}
LaunchedEffect(items) {
if (items != null) {
(presenter.view?.activity as? MainActivity)?.ready = true
}
}

View file

@ -1,19 +1,10 @@
package eu.kanade.presentation.history.components
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.items
import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.components.RelativeDateHeader
@ -21,7 +12,6 @@ import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.history.HistoryUiModel
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.shimmerGradient
import eu.kanade.presentation.util.topPaddingValues
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -29,7 +19,7 @@ import java.text.DateFormat
@Composable
fun HistoryContent(
history: LazyPagingItems<HistoryUiModel>,
history: List<HistoryUiModel>,
contentPadding: PaddingValues,
onClickCover: (HistoryWithRelations) -> Unit,
onClickResume: (HistoryWithRelations) -> Unit,
@ -41,14 +31,21 @@ fun HistoryContent(
ScrollbarLazyColumn(
contentPadding = contentPadding + bottomNavPaddingValues + topPaddingValues,
state = rememberLazyListState(),
) {
items(history) { item ->
items(
items = history,
key = { "history-${it.hashCode()}" },
contentType = {
when (it) {
is HistoryUiModel.Header -> "header"
is HistoryUiModel.Item -> "item"
}
},
) { item ->
when (item) {
is HistoryUiModel.Header -> {
RelativeDateHeader(
modifier = Modifier
.animateItemPlacement(),
modifier = Modifier.animateItemPlacement(),
date = item.date,
relativeTime = relativeTime,
dateFormat = dateFormat,
@ -64,31 +61,6 @@ fun HistoryContent(
onClickDelete = { onClickDelete(value) },
)
}
null -> {
val transition = rememberInfiniteTransition()
val translateAnimation = transition.animateFloat(
initialValue = 0f,
targetValue = 1000f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = LinearEasing,
),
),
)
val brush = remember {
Brush.linearGradient(
colors = shimmerGradient,
start = Offset(0f, 0f),
end = Offset(
x = translateAnimation.value,
y = 00f,
),
)
}
HistoryItemShimmer(brush = brush)
}
}
}
}

View file

@ -1,15 +1,11 @@
package eu.kanade.presentation.history.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.Icon
@ -20,9 +16,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
@ -65,9 +58,10 @@ fun HistoryItem(
val textStyle = MaterialTheme.typography.bodyMedium
Text(
text = history.title,
fontWeight = FontWeight.SemiBold,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
style = textStyle.copy(fontWeight = FontWeight.SemiBold),
style = textStyle,
)
val readAt = remember { history.readAt?.toTimestampString() ?: "" }
Text(
@ -95,49 +89,6 @@ fun HistoryItem(
}
}
@Composable
fun HistoryItemShimmer(brush: Brush) {
Row(
modifier = Modifier
.height(HISTORY_ITEM_HEIGHT)
.padding(horizontal = horizontalPadding, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Box(
modifier = Modifier
.fillMaxHeight()
.aspectRatio(MangaCover.Book.ratio)
.clip(RoundedCornerShape(4.dp))
.drawBehind {
drawRect(brush = brush)
},
)
Column(
modifier = Modifier
.weight(1f)
.padding(start = horizontalPadding, end = 8.dp),
) {
Box(
modifier = Modifier
.drawBehind {
drawRect(brush = brush)
}
.height(14.dp)
.fillMaxWidth(0.70f),
)
Box(
modifier = Modifier
.padding(top = 4.dp)
.height(14.dp)
.fillMaxWidth(0.45f)
.drawBehind {
drawRect(brush = brush)
},
)
}
}
}
private val chapterFormatter = DecimalFormat(
"#.###",
DecimalFormatSymbols().apply { decimalSeparator = '.' },

View file

@ -1,9 +0,0 @@
package eu.kanade.presentation.util
import androidx.compose.ui.graphics.Color
val shimmerGradient = listOf(
Color.LightGray.copy(alpha = 0.8f),
Color.LightGray.copy(alpha = 0.2f),
Color.LightGray.copy(alpha = 0.8f),
)

View file

@ -5,14 +5,8 @@ import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.insertSeparators
import androidx.paging.map
import eu.kanade.core.util.insertSeparators
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.history.interactor.DeleteHistoryTable
@ -32,6 +26,7 @@ import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import logcat.LogPriority
@ -57,11 +52,11 @@ class HistoryPresenter(
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
@Composable
fun getLazyHistory(): LazyPagingItems<HistoryUiModel> {
val scope = rememberCoroutineScope()
fun getHistory(): Flow<List<HistoryUiModel>> {
val query = searchQuery ?: ""
val flow = remember(query) {
return remember(query) {
getHistory.subscribe(query)
.distinctUntilChanged()
.catch { error ->
logcat(LogPriority.ERROR, error)
_events.send(Event.InternalError)
@ -69,15 +64,11 @@ class HistoryPresenter(
.map { pagingData ->
pagingData.toHistoryUiModels()
}
.cachedIn(scope)
}
return flow.collectAsLazyPagingItems()
}
private fun PagingData<HistoryWithRelations>.toHistoryUiModels(): PagingData<HistoryUiModel> {
return this.map {
HistoryUiModel.Item(it)
}
private fun List<HistoryWithRelations>.toHistoryUiModels(): List<HistoryUiModel> {
return map { HistoryUiModel.Item(it) }
.insertSeparators { before, after ->
val beforeDate = before?.item?.readAt?.time?.toDateKey() ?: Date(0)
val afterDate = after?.item?.readAt?.time?.toDateKey() ?: Date(0)

View file

@ -26,13 +26,6 @@ JOIN (
) AS max_last_read
ON chapters.manga_id = max_last_read.manga_id;
countHistory:
SELECT count(*)
FROM historyView
WHERE historyView.readAt > 0
AND maxReadAtChapterId = historyView.chapterId
AND lower(historyView.title) LIKE ('%' || :query || '%');
history:
SELECT
id,
@ -50,8 +43,7 @@ FROM historyView
WHERE historyView.readAt > 0
AND maxReadAtChapterId = historyView.chapterId
AND lower(historyView.title) LIKE ('%' || :query || '%')
ORDER BY readAt DESC
LIMIT :limit OFFSET :offset;
ORDER BY readAt DESC;
getLatestHistory:
SELECT