Voyager on History tab (#8481)
parent
ba00d9e5d2
commit
bc3bb82651
@ -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,
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,30 +1,26 @@
|
|||||||
package eu.kanade.tachiyomi.ui.history
|
package eu.kanade.tachiyomi.ui.history
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import eu.kanade.presentation.history.HistoryScreen
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
|
import eu.kanade.domain.history.interactor.GetNextChapters
|
||||||
|
import eu.kanade.tachiyomi.ui.base.controller.BasicFullComposeController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.pushController
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class HistoryController : FullComposeController<HistoryPresenter>(), RootController {
|
class HistoryController : BasicFullComposeController(), RootController {
|
||||||
|
|
||||||
override fun createPresenter() = HistoryPresenter()
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ComposeContent() {
|
override fun ComposeContent() {
|
||||||
HistoryScreen(
|
Navigator(screen = HistoryScreen)
|
||||||
presenter = presenter,
|
|
||||||
onClickCover = { history ->
|
|
||||||
router.pushController(MangaController(history.mangaId))
|
|
||||||
},
|
|
||||||
onClickResume = { history ->
|
|
||||||
presenter.getNextChapterForManga(history.mangaId, history.chapterId)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resumeLastChapterRead() {
|
fun resumeLastChapterRead() {
|
||||||
presenter.resumeLastChapterRead()
|
val context = activity ?: return
|
||||||
|
viewScope.launchIO {
|
||||||
|
val chapter = Injekt.get<GetNextChapters>().await(onlyUnread = false).firstOrNull()
|
||||||
|
HistoryScreen.openChapter(context, chapter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.history
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
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.platform.LocalContext
|
||||||
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
|
import eu.kanade.presentation.history.HistoryScreen
|
||||||
|
import eu.kanade.presentation.history.components.HistoryDeleteAllDialog
|
||||||
|
import eu.kanade.presentation.history.components.HistoryDeleteDialog
|
||||||
|
import eu.kanade.presentation.util.LocalRouter
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.ui.base.controller.pushController
|
||||||
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
|
||||||
|
object HistoryScreen : Screen {
|
||||||
|
|
||||||
|
private val snackbarHostState = SnackbarHostState()
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun Content() {
|
||||||
|
val router = LocalRouter.currentOrThrow
|
||||||
|
val context = LocalContext.current
|
||||||
|
val screenModel = rememberScreenModel { HistoryScreenModel() }
|
||||||
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
|
HistoryScreen(
|
||||||
|
state = state,
|
||||||
|
snackbarHostState = snackbarHostState,
|
||||||
|
incognitoMode = screenModel.isIncognitoMode,
|
||||||
|
downloadedOnlyMode = screenModel.isDownloadOnly,
|
||||||
|
onSearchQueryChange = screenModel::updateSearchQuery,
|
||||||
|
onClickCover = { router.pushController(MangaController(it)) },
|
||||||
|
onClickResume = screenModel::getNextChapterForManga,
|
||||||
|
onDialogChange = screenModel::setDialog,
|
||||||
|
)
|
||||||
|
|
||||||
|
val onDismissRequest = { screenModel.setDialog(null) }
|
||||||
|
when (val dialog = state.dialog) {
|
||||||
|
is HistoryScreenModel.Dialog.Delete -> {
|
||||||
|
HistoryDeleteDialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
onDelete = { all ->
|
||||||
|
if (all) {
|
||||||
|
screenModel.removeAllFromHistory(dialog.history.mangaId)
|
||||||
|
} else {
|
||||||
|
screenModel.removeFromHistory(dialog.history)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is HistoryScreenModel.Dialog.DeleteAll -> {
|
||||||
|
HistoryDeleteAllDialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
onDelete = screenModel::removeAllHistory,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(state.list) {
|
||||||
|
if (state.list != null) {
|
||||||
|
(context as? MainActivity)?.ready = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
screenModel.events.collectLatest { e ->
|
||||||
|
when (e) {
|
||||||
|
HistoryScreenModel.Event.InternalError ->
|
||||||
|
snackbarHostState.showSnackbar(context.getString(R.string.internal_error))
|
||||||
|
HistoryScreenModel.Event.HistoryCleared ->
|
||||||
|
snackbarHostState.showSnackbar(context.getString(R.string.clear_history_completed))
|
||||||
|
is HistoryScreenModel.Event.OpenChapter -> openChapter(context, e.chapter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun openChapter(context: Context, chapter: Chapter?) {
|
||||||
|
if (chapter != null) {
|
||||||
|
val intent = ReaderActivity.newIntent(context, chapter.mangaId, chapter.id)
|
||||||
|
context.startActivity(intent)
|
||||||
|
} else {
|
||||||
|
snackbarHostState.showSnackbar(context.getString(R.string.no_next_chapter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue