mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-17 14:39:18 +01:00
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:
parent
8d1f99a480
commit
42b0e3e438
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.data.history
|
package eu.kanade.data.history
|
||||||
|
|
||||||
import androidx.paging.PagingSource
|
|
||||||
import eu.kanade.data.DatabaseHandler
|
import eu.kanade.data.DatabaseHandler
|
||||||
import eu.kanade.data.chapter.chapterMapper
|
import eu.kanade.data.chapter.chapterMapper
|
||||||
import eu.kanade.data.manga.mangaMapper
|
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.history.repository.HistoryRepository
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import eu.kanade.domain.manga.model.Manga
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
|
||||||
class HistoryRepositoryImpl(
|
class HistoryRepositoryImpl(
|
||||||
private val handler: DatabaseHandler,
|
private val handler: DatabaseHandler,
|
||||||
) : HistoryRepository {
|
) : HistoryRepository {
|
||||||
|
|
||||||
override fun getHistory(query: String): PagingSource<Long, HistoryWithRelations> {
|
override fun getHistory(query: String): Flow<List<HistoryWithRelations>> {
|
||||||
return handler.subscribeToPagingSource(
|
return handler.subscribeToList {
|
||||||
countQuery = { historyViewQueries.countHistory(query) },
|
historyViewQueries.history(query, historyWithRelationsMapper)
|
||||||
queryProvider = { limit, offset ->
|
}
|
||||||
historyViewQueries.history(query, limit, offset, historyWithRelationsMapper)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getLastHistory(): HistoryWithRelations? {
|
override suspend fun getLastHistory(): HistoryWithRelations? {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package eu.kanade.domain.history.interactor
|
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.model.HistoryWithRelations
|
||||||
import eu.kanade.domain.history.repository.HistoryRepository
|
import eu.kanade.domain.history.repository.HistoryRepository
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -10,12 +7,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
class GetHistory(
|
class GetHistory(
|
||||||
private val repository: HistoryRepository,
|
private val repository: HistoryRepository,
|
||||||
) {
|
) {
|
||||||
|
fun subscribe(query: String): Flow<List<HistoryWithRelations>> {
|
||||||
fun subscribe(query: String): Flow<PagingData<HistoryWithRelations>> {
|
return repository.getHistory(query)
|
||||||
return Pager(
|
|
||||||
PagingConfig(pageSize = 25),
|
|
||||||
) {
|
|
||||||
repository.getHistory(query)
|
|
||||||
}.flow
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package eu.kanade.domain.history.repository
|
package eu.kanade.domain.history.repository
|
||||||
|
|
||||||
import androidx.paging.PagingSource
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
import eu.kanade.domain.history.model.HistoryUpdate
|
import eu.kanade.domain.history.model.HistoryUpdate
|
||||||
import eu.kanade.domain.history.model.HistoryWithRelations
|
import eu.kanade.domain.history.model.HistoryWithRelations
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface HistoryRepository {
|
interface HistoryRepository {
|
||||||
|
|
||||||
fun getHistory(query: String): PagingSource<Long, HistoryWithRelations>
|
fun getHistory(query: String): Flow<List<HistoryWithRelations>>
|
||||||
|
|
||||||
suspend fun getLastHistory(): HistoryWithRelations?
|
suspend fun getLastHistory(): HistoryWithRelations?
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@ package eu.kanade.presentation.history
|
|||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.paging.LoadState
|
|
||||||
import eu.kanade.domain.history.model.HistoryWithRelations
|
import eu.kanade.domain.history.model.HistoryWithRelations
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
import eu.kanade.presentation.components.LoadingScreen
|
import eu.kanade.presentation.components.LoadingScreen
|
||||||
@ -39,20 +40,25 @@ fun HistoryScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
val items = presenter.getLazyHistory()
|
val items by presenter.getHistory().collectAsState(initial = null)
|
||||||
when {
|
items.let {
|
||||||
items.loadState.refresh is LoadState.Loading && items.itemCount < 1 -> LoadingScreen()
|
if (it == null) {
|
||||||
items.loadState.refresh is LoadState.NotLoading && items.itemCount < 1 -> EmptyScreen(textResource = R.string.information_no_recent_manga)
|
LoadingScreen()
|
||||||
else -> HistoryContent(
|
} else if (it.isEmpty()) {
|
||||||
history = items,
|
EmptyScreen(textResource = R.string.information_no_recent_manga)
|
||||||
contentPadding = contentPadding,
|
} else {
|
||||||
onClickCover = onClickCover,
|
HistoryContent(
|
||||||
onClickResume = onClickResume,
|
history = it,
|
||||||
onClickDelete = { presenter.dialog = Dialog.Delete(it) },
|
contentPadding = contentPadding,
|
||||||
)
|
onClickCover = onClickCover,
|
||||||
|
onClickResume = onClickResume,
|
||||||
|
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
|
(presenter.view?.activity as? MainActivity)?.ready = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,10 @@
|
|||||||
package eu.kanade.presentation.history.components
|
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.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
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.history.model.HistoryWithRelations
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
import eu.kanade.presentation.components.RelativeDateHeader
|
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.history.HistoryUiModel
|
||||||
import eu.kanade.presentation.util.bottomNavPaddingValues
|
import eu.kanade.presentation.util.bottomNavPaddingValues
|
||||||
import eu.kanade.presentation.util.plus
|
import eu.kanade.presentation.util.plus
|
||||||
import eu.kanade.presentation.util.shimmerGradient
|
|
||||||
import eu.kanade.presentation.util.topPaddingValues
|
import eu.kanade.presentation.util.topPaddingValues
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -29,7 +19,7 @@ import java.text.DateFormat
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HistoryContent(
|
fun HistoryContent(
|
||||||
history: LazyPagingItems<HistoryUiModel>,
|
history: List<HistoryUiModel>,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
onClickCover: (HistoryWithRelations) -> Unit,
|
onClickCover: (HistoryWithRelations) -> Unit,
|
||||||
onClickResume: (HistoryWithRelations) -> Unit,
|
onClickResume: (HistoryWithRelations) -> Unit,
|
||||||
@ -41,14 +31,21 @@ fun HistoryContent(
|
|||||||
|
|
||||||
ScrollbarLazyColumn(
|
ScrollbarLazyColumn(
|
||||||
contentPadding = contentPadding + bottomNavPaddingValues + topPaddingValues,
|
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) {
|
when (item) {
|
||||||
is HistoryUiModel.Header -> {
|
is HistoryUiModel.Header -> {
|
||||||
RelativeDateHeader(
|
RelativeDateHeader(
|
||||||
modifier = Modifier
|
modifier = Modifier.animateItemPlacement(),
|
||||||
.animateItemPlacement(),
|
|
||||||
date = item.date,
|
date = item.date,
|
||||||
relativeTime = relativeTime,
|
relativeTime = relativeTime,
|
||||||
dateFormat = dateFormat,
|
dateFormat = dateFormat,
|
||||||
@ -64,31 +61,6 @@ fun HistoryContent(
|
|||||||
onClickDelete = { onClickDelete(value) },
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
package eu.kanade.presentation.history.components
|
package eu.kanade.presentation.history.components
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Delete
|
import androidx.compose.material.icons.outlined.Delete
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@ -20,9 +16,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
@ -65,9 +58,10 @@ fun HistoryItem(
|
|||||||
val textStyle = MaterialTheme.typography.bodyMedium
|
val textStyle = MaterialTheme.typography.bodyMedium
|
||||||
Text(
|
Text(
|
||||||
text = history.title,
|
text = history.title,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
maxLines = 2,
|
maxLines = 2,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
style = textStyle.copy(fontWeight = FontWeight.SemiBold),
|
style = textStyle,
|
||||||
)
|
)
|
||||||
val readAt = remember { history.readAt?.toTimestampString() ?: "" }
|
val readAt = remember { history.readAt?.toTimestampString() ?: "" }
|
||||||
Text(
|
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(
|
private val chapterFormatter = DecimalFormat(
|
||||||
"#.###",
|
"#.###",
|
||||||
DecimalFormatSymbols().apply { decimalSeparator = '.' },
|
DecimalFormatSymbols().apply { decimalSeparator = '.' },
|
||||||
|
@ -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),
|
|
||||||
)
|
|
@ -5,14 +5,8 @@ import androidx.compose.runtime.Stable
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.paging.PagingData
|
import eu.kanade.core.util.insertSeparators
|
||||||
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.domain.base.BasePreferences
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
import eu.kanade.domain.history.interactor.DeleteHistoryTable
|
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.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
@ -57,11 +52,11 @@ class HistoryPresenter(
|
|||||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun getLazyHistory(): LazyPagingItems<HistoryUiModel> {
|
fun getHistory(): Flow<List<HistoryUiModel>> {
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val query = searchQuery ?: ""
|
val query = searchQuery ?: ""
|
||||||
val flow = remember(query) {
|
return remember(query) {
|
||||||
getHistory.subscribe(query)
|
getHistory.subscribe(query)
|
||||||
|
.distinctUntilChanged()
|
||||||
.catch { error ->
|
.catch { error ->
|
||||||
logcat(LogPriority.ERROR, error)
|
logcat(LogPriority.ERROR, error)
|
||||||
_events.send(Event.InternalError)
|
_events.send(Event.InternalError)
|
||||||
@ -69,15 +64,11 @@ class HistoryPresenter(
|
|||||||
.map { pagingData ->
|
.map { pagingData ->
|
||||||
pagingData.toHistoryUiModels()
|
pagingData.toHistoryUiModels()
|
||||||
}
|
}
|
||||||
.cachedIn(scope)
|
|
||||||
}
|
}
|
||||||
return flow.collectAsLazyPagingItems()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PagingData<HistoryWithRelations>.toHistoryUiModels(): PagingData<HistoryUiModel> {
|
private fun List<HistoryWithRelations>.toHistoryUiModels(): List<HistoryUiModel> {
|
||||||
return this.map {
|
return map { HistoryUiModel.Item(it) }
|
||||||
HistoryUiModel.Item(it)
|
|
||||||
}
|
|
||||||
.insertSeparators { before, after ->
|
.insertSeparators { before, after ->
|
||||||
val beforeDate = before?.item?.readAt?.time?.toDateKey() ?: Date(0)
|
val beforeDate = before?.item?.readAt?.time?.toDateKey() ?: Date(0)
|
||||||
val afterDate = after?.item?.readAt?.time?.toDateKey() ?: Date(0)
|
val afterDate = after?.item?.readAt?.time?.toDateKey() ?: Date(0)
|
||||||
|
@ -26,13 +26,6 @@ JOIN (
|
|||||||
) AS max_last_read
|
) AS max_last_read
|
||||||
ON chapters.manga_id = max_last_read.manga_id;
|
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:
|
history:
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
@ -50,8 +43,7 @@ FROM historyView
|
|||||||
WHERE historyView.readAt > 0
|
WHERE historyView.readAt > 0
|
||||||
AND maxReadAtChapterId = historyView.chapterId
|
AND maxReadAtChapterId = historyView.chapterId
|
||||||
AND lower(historyView.title) LIKE ('%' || :query || '%')
|
AND lower(historyView.title) LIKE ('%' || :query || '%')
|
||||||
ORDER BY readAt DESC
|
ORDER BY readAt DESC;
|
||||||
LIMIT :limit OFFSET :offset;
|
|
||||||
|
|
||||||
getLatestHistory:
|
getLatestHistory:
|
||||||
SELECT
|
SELECT
|
||||||
|
Loading…
Reference in New Issue
Block a user