mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-06-28 08:16:04 +02:00
157 lines
5.8 KiB
Kotlin
157 lines
5.8 KiB
Kotlin
package eu.kanade.presentation.history
|
|
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.lazy.items
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.outlined.DeleteSweep
|
|
import androidx.compose.material3.SnackbarHost
|
|
import androidx.compose.material3.SnackbarHostState
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
|
import eu.kanade.presentation.components.AppBar
|
|
import eu.kanade.presentation.components.AppBarActions
|
|
import eu.kanade.presentation.components.AppBarTitle
|
|
import eu.kanade.presentation.components.SearchToolbar
|
|
import eu.kanade.presentation.components.relativeDateText
|
|
import eu.kanade.presentation.history.components.HistoryItem
|
|
import eu.kanade.presentation.theme.TachiyomiTheme
|
|
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
|
|
import kotlinx.collections.immutable.persistentListOf
|
|
import tachiyomi.domain.history.model.HistoryWithRelations
|
|
import tachiyomi.i18n.MR
|
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
|
import tachiyomi.presentation.core.components.ListGroupHeader
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
|
import tachiyomi.presentation.core.i18n.stringResource
|
|
import tachiyomi.presentation.core.screens.EmptyScreen
|
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
|
import java.util.Date
|
|
|
|
@Composable
|
|
fun HistoryScreen(
|
|
state: HistoryScreenModel.State,
|
|
snackbarHostState: SnackbarHostState,
|
|
onSearchQueryChange: (String?) -> Unit,
|
|
onClickCover: (mangaId: Long) -> Unit,
|
|
onClickResume: (mangaId: Long, chapterId: Long) -> Unit,
|
|
onDialogChange: (HistoryScreenModel.Dialog?) -> Unit,
|
|
) {
|
|
Scaffold(
|
|
topBar = { scrollBehavior ->
|
|
SearchToolbar(
|
|
titleContent = { AppBarTitle(stringResource(MR.strings.history)) },
|
|
searchQuery = state.searchQuery,
|
|
onChangeSearchQuery = onSearchQueryChange,
|
|
actions = {
|
|
AppBarActions(
|
|
persistentListOf(
|
|
AppBar.Action(
|
|
title = stringResource(MR.strings.pref_clear_history),
|
|
icon = Icons.Outlined.DeleteSweep,
|
|
onClick = {
|
|
onDialogChange(HistoryScreenModel.Dialog.DeleteAll)
|
|
},
|
|
),
|
|
),
|
|
)
|
|
},
|
|
scrollBehavior = scrollBehavior,
|
|
)
|
|
},
|
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
|
) { contentPadding ->
|
|
state.list.let {
|
|
if (it == null) {
|
|
LoadingScreen(Modifier.padding(contentPadding))
|
|
} else if (it.isEmpty()) {
|
|
val msg = if (!state.searchQuery.isNullOrEmpty()) {
|
|
MR.strings.no_results_found
|
|
} else {
|
|
MR.strings.information_no_recent_manga
|
|
}
|
|
EmptyScreen(
|
|
stringRes = msg,
|
|
modifier = Modifier.padding(contentPadding),
|
|
)
|
|
} else {
|
|
HistoryScreenContent(
|
|
history = it,
|
|
contentPadding = contentPadding,
|
|
onClickCover = { history -> onClickCover(history.mangaId) },
|
|
onClickResume = { history -> onClickResume(history.mangaId, history.chapterId) },
|
|
onClickDelete = { item -> onDialogChange(HistoryScreenModel.Dialog.Delete(item)) },
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun HistoryScreenContent(
|
|
history: List<HistoryUiModel>,
|
|
contentPadding: PaddingValues,
|
|
onClickCover: (HistoryWithRelations) -> Unit,
|
|
onClickResume: (HistoryWithRelations) -> Unit,
|
|
onClickDelete: (HistoryWithRelations) -> Unit,
|
|
) {
|
|
FastScrollLazyColumn(
|
|
contentPadding = contentPadding,
|
|
) {
|
|
items(
|
|
items = history,
|
|
key = { "history-${it.hashCode()}" },
|
|
contentType = {
|
|
when (it) {
|
|
is HistoryUiModel.Header -> "header"
|
|
is HistoryUiModel.Item -> "item"
|
|
}
|
|
},
|
|
) { item ->
|
|
when (item) {
|
|
is HistoryUiModel.Header -> {
|
|
ListGroupHeader(
|
|
modifier = Modifier.animateItemPlacement(),
|
|
text = relativeDateText(item.date),
|
|
)
|
|
}
|
|
is HistoryUiModel.Item -> {
|
|
val value = item.item
|
|
HistoryItem(
|
|
modifier = Modifier.animateItemPlacement(),
|
|
history = value,
|
|
onClickCover = { onClickCover(value) },
|
|
onClickResume = { onClickResume(value) },
|
|
onClickDelete = { onClickDelete(value) },
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sealed interface HistoryUiModel {
|
|
data class Header(val date: Date) : HistoryUiModel
|
|
data class Item(val item: HistoryWithRelations) : HistoryUiModel
|
|
}
|
|
|
|
@PreviewLightDark
|
|
@Composable
|
|
internal fun HistoryScreenPreviews(
|
|
@PreviewParameter(HistoryScreenModelStateProvider::class)
|
|
historyState: HistoryScreenModel.State,
|
|
) {
|
|
TachiyomiTheme {
|
|
HistoryScreen(
|
|
state = historyState,
|
|
snackbarHostState = SnackbarHostState(),
|
|
onSearchQueryChange = {},
|
|
onClickCover = {},
|
|
onClickResume = { _, _ -> run {} },
|
|
onDialogChange = {},
|
|
)
|
|
}
|
|
}
|