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
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import eu.kanade.presentation.history.HistoryScreen
|
||||
import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
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.pushController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class HistoryController : FullComposeController<HistoryPresenter>(), RootController {
|
||||
|
||||
override fun createPresenter() = HistoryPresenter()
|
||||
class HistoryController : BasicFullComposeController(), RootController {
|
||||
|
||||
@Composable
|
||||
override fun ComposeContent() {
|
||||
HistoryScreen(
|
||||
presenter = presenter,
|
||||
onClickCover = { history ->
|
||||
router.pushController(MangaController(history.mangaId))
|
||||
},
|
||||
onClickResume = { history ->
|
||||
presenter.getNextChapterForManga(history.mangaId, history.chapterId)
|
||||
},
|
||||
)
|
||||
Navigator(screen = HistoryScreen)
|
||||
}
|
||||
|
||||
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