Voyager on History tab (#8481)

This commit is contained in:
Ivan Iskandar
2022-11-09 21:26:29 +07:00
committed by GitHub
parent ba00d9e5d2
commit bc3bb82651
9 changed files with 233 additions and 186 deletions

View File

@@ -8,9 +8,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@Composable
fun LoadingScreen() {
fun LoadingScreen(modifier: Modifier = Modifier) {
Box(
modifier = Modifier.fillMaxSize(),
modifier = modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator()

View File

@@ -1,110 +1,80 @@
package eu.kanade.presentation.history
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.DeleteSweep
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ScaffoldDefaults
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import eu.kanade.domain.history.model.HistoryWithRelations
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.history.components.HistoryContent
import eu.kanade.presentation.history.components.HistoryDeleteAllDialog
import eu.kanade.presentation.history.components.HistoryDeleteDialog
import eu.kanade.presentation.history.components.HistoryToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.history.HistoryPresenter
import eu.kanade.tachiyomi.ui.history.HistoryPresenter.Dialog
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
import eu.kanade.tachiyomi.ui.history.HistoryState
import eu.kanade.tachiyomi.widget.TachiyomiBottomNavigationView
import kotlinx.coroutines.flow.collectLatest
import java.util.Date
@Composable
fun HistoryScreen(
presenter: HistoryPresenter,
onClickCover: (HistoryWithRelations) -> Unit,
onClickResume: (HistoryWithRelations) -> Unit,
state: HistoryState,
snackbarHostState: SnackbarHostState,
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
onSearchQueryChange: (String?) -> Unit,
onClickCover: (mangaId: Long) -> Unit,
onClickResume: (mangaId: Long, chapterId: Long) -> Unit,
onDialogChange: (HistoryScreenModel.Dialog?) -> Unit,
) {
val context = LocalContext.current
Scaffold(
topBar = { scrollBehavior ->
HistoryToolbar(
state = presenter,
incognitoMode = presenter.isIncognitoMode,
downloadedOnlyMode = presenter.isDownloadOnly,
SearchToolbar(
titleContent = { AppBarTitle(stringResource(R.string.history)) },
searchQuery = state.searchQuery,
onChangeSearchQuery = onSearchQueryChange,
actions = {
IconButton(onClick = { onDialogChange(HistoryScreenModel.Dialog.DeleteAll) }) {
Icon(
Icons.Outlined.DeleteSweep,
contentDescription = stringResource(R.string.pref_clear_history),
)
}
},
downloadedOnlyMode = downloadedOnlyMode,
incognitoMode = incognitoMode,
scrollBehavior = scrollBehavior,
)
},
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
contentWindowInsets = TachiyomiBottomNavigationView.withBottomNavInset(ScaffoldDefaults.contentWindowInsets),
) { contentPadding ->
val items by presenter.getHistory().collectAsState(initial = null)
val contentPaddingWithNavBar = TachiyomiBottomNavigationView.withBottomNavPadding(contentPadding)
items.let {
state.list.let {
if (it == null) {
LoadingScreen()
LoadingScreen(modifier = Modifier.padding(contentPadding))
} else if (it.isEmpty()) {
EmptyScreen(
textResource = R.string.information_no_recent_manga,
modifier = Modifier.padding(contentPaddingWithNavBar),
modifier = Modifier.padding(contentPadding),
)
} else {
HistoryContent(
history = it,
contentPadding = contentPaddingWithNavBar,
onClickCover = onClickCover,
onClickResume = onClickResume,
onClickDelete = { item -> presenter.dialog = Dialog.Delete(item) },
contentPadding = contentPadding,
onClickCover = { history -> onClickCover(history.mangaId) },
onClickResume = { history -> onClickResume(history.mangaId, history.chapterId) },
onClickDelete = { item -> onDialogChange(HistoryScreenModel.Dialog.Delete(item)) },
)
}
}
LaunchedEffect(items) {
if (items != null) {
(presenter.view?.activity as? MainActivity)?.ready = true
}
}
}
val onDismissRequest = { presenter.dialog = null }
when (val dialog = presenter.dialog) {
is Dialog.Delete -> {
HistoryDeleteDialog(
onDismissRequest = onDismissRequest,
onDelete = { all ->
if (all) {
presenter.removeAllFromHistory(dialog.history.mangaId)
} else {
presenter.removeFromHistory(dialog.history)
}
},
)
}
is Dialog.DeleteAll -> {
HistoryDeleteAllDialog(
onDismissRequest = onDismissRequest,
onDelete = {
presenter.removeAllHistory()
},
)
}
null -> {}
}
LaunchedEffect(Unit) {
presenter.events.collectLatest { event ->
when (event) {
HistoryPresenter.Event.InternalError -> context.toast(R.string.internal_error)
HistoryPresenter.Event.NoNextChapterFound -> context.toast(R.string.no_next_chapter)
is HistoryPresenter.Event.OpenChapter -> {
val intent = ReaderActivity.newIntent(context, event.chapter.mangaId, event.chapter.id)
context.startActivity(intent)
}
}
}
}
}

View File

@@ -1,36 +0,0 @@
package eu.kanade.presentation.history.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.DeleteSweep
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.history.HistoryPresenter
import eu.kanade.tachiyomi.ui.history.HistoryState
@Composable
fun HistoryToolbar(
state: HistoryState,
scrollBehavior: TopAppBarScrollBehavior,
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
) {
SearchToolbar(
titleContent = { AppBarTitle(stringResource(R.string.history)) },
searchQuery = state.searchQuery,
onChangeSearchQuery = { state.searchQuery = it },
actions = {
IconButton(onClick = { state.dialog = HistoryPresenter.Dialog.DeleteAll }) {
Icon(Icons.Outlined.DeleteSweep, contentDescription = stringResource(R.string.pref_clear_history))
}
},
downloadedOnlyMode = downloadedOnlyMode,
incognitoMode = incognitoMode,
scrollBehavior = scrollBehavior,
)
}