Move a few Dialogs to Compose (#7861)
* Move a few Dialogs to Compose - Separating dialogs that are not needed in the PR for the move to Compose on the Browse Source screen - ChangeMangaCategoriesDialog and AddDuplicateMangaDialog will be removed in the Browse Source screen PR * Review changes
This commit is contained in:
@@ -2,10 +2,19 @@ package eu.kanade.tachiyomi.ui.manga
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.pushController
|
||||
@@ -46,3 +55,48 @@ class AddDuplicateMangaDialog(bundle: Bundle? = null) : DialogController(bundle)
|
||||
.create()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DuplicateDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onConfirm: () -> Unit,
|
||||
onOpenManga: () -> Unit,
|
||||
duplicateFrom: Source,
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
confirmButton = {
|
||||
Row {
|
||||
TextButton(onClick = {
|
||||
onDismissRequest()
|
||||
onOpenManga()
|
||||
},) {
|
||||
Text(text = stringResource(id = R.string.action_show_manga))
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
TextButton(onClick = onDismissRequest) {
|
||||
Text(text = stringResource(id = android.R.string.cancel))
|
||||
}
|
||||
TextButton(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onConfirm()
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.action_add))
|
||||
}
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Text(text = stringResource(id = R.string.are_you_sure))
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = R.string.confirm_manga_add_duplicate,
|
||||
duplicateFrom.name,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,26 +6,26 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.OnBackPressedDispatcherOwner
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.core.os.bundleOf
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.data.chapter.NoChaptersException
|
||||
import eu.kanade.domain.category.model.Category
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.presentation.components.ChangeCategoryDialog
|
||||
import eu.kanade.presentation.components.ChapterDownloadAction
|
||||
import eu.kanade.presentation.components.LoadingScreen
|
||||
import eu.kanade.presentation.manga.DownloadAction
|
||||
import eu.kanade.presentation.manga.MangaScreen
|
||||
import eu.kanade.presentation.manga.components.DeleteChaptersDialog
|
||||
import eu.kanade.presentation.util.calculateWindowWidthSizeClass
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
@@ -41,11 +41,12 @@ import eu.kanade.tachiyomi.ui.browse.migration.search.SearchController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.latest.LatestUpdatesController
|
||||
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
|
||||
import eu.kanade.tachiyomi.ui.category.CategoryController
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaPresenter.Dialog
|
||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersSettingsSheet
|
||||
import eu.kanade.tachiyomi.ui.manga.chapter.DownloadCustomChaptersDialog
|
||||
import eu.kanade.tachiyomi.ui.manga.chapter.DownloadCustomAmountDialog
|
||||
import eu.kanade.tachiyomi.ui.manga.info.MangaFullCoverDialog
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackSearchDialog
|
||||
@@ -54,21 +55,13 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.recent.history.HistoryController
|
||||
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
|
||||
import eu.kanade.tachiyomi.widget.materialdialogs.await
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority
|
||||
import eu.kanade.domain.chapter.model.Chapter as DomainChapter
|
||||
|
||||
class MangaController :
|
||||
FullComposeController<MangaPresenter>,
|
||||
ChangeMangaCategoriesDialog.Listener,
|
||||
DownloadCustomChaptersDialog.Listener {
|
||||
class MangaController : FullComposeController<MangaPresenter> {
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : this(bundle.getLong(MANGA_EXTRA))
|
||||
@@ -112,9 +105,19 @@ class MangaController :
|
||||
@Composable
|
||||
override fun ComposeContent() {
|
||||
val state by presenter.state.collectAsState()
|
||||
val dialog by derivedStateOf {
|
||||
when (val state = state) {
|
||||
MangaScreenState.Loading -> null
|
||||
is MangaScreenState.Success -> state.dialog
|
||||
}
|
||||
}
|
||||
|
||||
if (state is MangaScreenState.Success) {
|
||||
val successState = state as MangaScreenState.Success
|
||||
val isHttpSource = remember { successState.source is HttpSource }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
MangaScreen(
|
||||
state = successState,
|
||||
snackbarHostState = snackbarHostState,
|
||||
@@ -133,16 +136,67 @@ class MangaController :
|
||||
onCoverClicked = this::openCoverDialog,
|
||||
onShareClicked = this::shareManga.takeIf { isHttpSource },
|
||||
onDownloadActionClicked = this::runDownloadChapterAction.takeIf { !successState.source.isLocalOrStub() },
|
||||
onEditCategoryClicked = this::onCategoriesClick.takeIf { successState.manga.favorite },
|
||||
onEditCategoryClicked = presenter::promptChangeCategories.takeIf { successState.manga.favorite },
|
||||
onMigrateClicked = this::migrateManga.takeIf { successState.manga.favorite },
|
||||
onMultiBookmarkClicked = presenter::bookmarkChapters,
|
||||
onMultiMarkAsReadClicked = presenter::markChaptersRead,
|
||||
onMarkPreviousAsReadClicked = presenter::markPreviousChapterRead,
|
||||
onMultiDeleteClicked = this::deleteChaptersWithConfirmation,
|
||||
onMultiDeleteClicked = presenter::showDeleteChapterDialog,
|
||||
onChapterSelected = presenter::toggleSelection,
|
||||
onAllChapterSelected = presenter::toggleAllSelection,
|
||||
onInvertSelection = presenter::invertSelection,
|
||||
)
|
||||
|
||||
val onDismissRequest = { presenter.dismissDialog() }
|
||||
when (val dialog = dialog) {
|
||||
is Dialog.ChangeCategory -> {
|
||||
ChangeCategoryDialog(
|
||||
initialSelection = dialog.initialSelection,
|
||||
onDismissRequest = onDismissRequest,
|
||||
onEditCategories = {
|
||||
router.pushController(CategoryController())
|
||||
},
|
||||
onConfirm = { include, _ ->
|
||||
presenter.moveMangaToCategoriesAndAddToLibrary(dialog.manga, include)
|
||||
},
|
||||
)
|
||||
}
|
||||
is Dialog.DeleteChapters -> {
|
||||
DeleteChaptersDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirm = {
|
||||
deleteChapters(dialog.chapters)
|
||||
},
|
||||
)
|
||||
}
|
||||
is Dialog.DownloadCustomAmount -> {
|
||||
DownloadCustomAmountDialog(
|
||||
maxAmount = dialog.max,
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirm = { amount ->
|
||||
val chaptersToDownload = presenter.getUnreadChaptersSorted().take(amount)
|
||||
if (chaptersToDownload.isNotEmpty()) {
|
||||
scope.launch { downloadChapters(chaptersToDownload) }
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
is Dialog.DuplicateManga -> {
|
||||
DuplicateDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirm = {
|
||||
presenter.toggleFavorite(
|
||||
onRemoved = {},
|
||||
onAdded = {},
|
||||
checkDuplicate = false,
|
||||
)
|
||||
},
|
||||
onOpenManga = { router.pushController(MangaController(dialog.duplicate.id)) },
|
||||
duplicateFrom = presenter.getSourceOrStub(dialog.duplicate),
|
||||
)
|
||||
}
|
||||
null -> {}
|
||||
}
|
||||
} else {
|
||||
LoadingScreen()
|
||||
}
|
||||
@@ -206,30 +260,10 @@ class MangaController :
|
||||
}
|
||||
}
|
||||
|
||||
private fun onFavoriteClick(checkDuplicate: Boolean = true) {
|
||||
private fun onFavoriteClick() {
|
||||
presenter.toggleFavorite(
|
||||
onRemoved = this::onFavoriteRemoved,
|
||||
onAdded = { activity?.toast(activity?.getString(R.string.manga_added_library)) },
|
||||
onDuplicateExists = if (checkDuplicate) {
|
||||
{
|
||||
AddDuplicateMangaDialog(
|
||||
target = this,
|
||||
libraryManga = it,
|
||||
onAddToLibrary = { onFavoriteClick(checkDuplicate = false) },
|
||||
).showDialog(router)
|
||||
}
|
||||
} else null,
|
||||
onRequireCategory = { manga, categories ->
|
||||
val ids = runBlocking { presenter.getMangaCategoryIds(manga) }
|
||||
val preselected = categories.map {
|
||||
if (it.id in ids) {
|
||||
QuadStateTextView.State.CHECKED.ordinal
|
||||
} else {
|
||||
QuadStateTextView.State.UNCHECKED.ordinal
|
||||
}
|
||||
}.toTypedArray()
|
||||
showChangeCategoryDialog(manga, categories, preselected)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -249,40 +283,6 @@ class MangaController :
|
||||
}
|
||||
}
|
||||
|
||||
private fun onCategoriesClick() {
|
||||
viewScope.launchIO {
|
||||
val manga = presenter.manga ?: return@launchIO
|
||||
val categories = presenter.getCategories()
|
||||
|
||||
val ids = presenter.getMangaCategoryIds(manga)
|
||||
val preselected = categories.map {
|
||||
if (it.id in ids) {
|
||||
QuadStateTextView.State.CHECKED.ordinal
|
||||
} else {
|
||||
QuadStateTextView.State.UNCHECKED.ordinal
|
||||
}
|
||||
}.toTypedArray()
|
||||
|
||||
withUIContext {
|
||||
showChangeCategoryDialog(manga, categories, preselected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showChangeCategoryDialog(manga: Manga, categories: List<Category>, preselected: Array<Int>) {
|
||||
ChangeMangaCategoriesDialog(this, listOf(manga), categories, preselected)
|
||||
.showDialog(router)
|
||||
}
|
||||
|
||||
override fun updateCategoriesForMangas(
|
||||
mangas: List<Manga>,
|
||||
addCategories: List<Category>,
|
||||
removeCategories: List<Category>,
|
||||
) {
|
||||
val changed = mangas.firstOrNull() ?: return
|
||||
presenter.moveMangaToCategoriesAndAddToLibrary(changed, addCategories)
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search using the provided query.
|
||||
*
|
||||
@@ -427,15 +427,6 @@ class MangaController :
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteChaptersWithConfirmation(chapters: List<DomainChapter>) {
|
||||
viewScope.launch {
|
||||
val result = MaterialAlertDialogBuilder(activity!!)
|
||||
.setMessage(R.string.confirm_delete_chapters)
|
||||
.await(android.R.string.ok, android.R.string.cancel)
|
||||
if (result == AlertDialog.BUTTON_POSITIVE) deleteChapters(chapters)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteChapters(chapters: List<DomainChapter>) {
|
||||
if (chapters.isEmpty()) return
|
||||
presenter.deleteChapters(chapters)
|
||||
@@ -449,7 +440,7 @@ class MangaController :
|
||||
DownloadAction.NEXT_5_CHAPTERS -> presenter.getUnreadChaptersSorted().take(5)
|
||||
DownloadAction.NEXT_10_CHAPTERS -> presenter.getUnreadChaptersSorted().take(10)
|
||||
DownloadAction.CUSTOM -> {
|
||||
showCustomDownloadDialog()
|
||||
presenter.showDownloadCustomDialog()
|
||||
return
|
||||
}
|
||||
DownloadAction.UNREAD_CHAPTERS -> presenter.getUnreadChapters()
|
||||
@@ -462,21 +453,6 @@ class MangaController :
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCustomDownloadDialog() {
|
||||
val availableChapters = presenter.processedChapters?.count() ?: return
|
||||
DownloadCustomChaptersDialog(
|
||||
this,
|
||||
availableChapters,
|
||||
).showDialog(router)
|
||||
}
|
||||
|
||||
override fun downloadCustomChapters(amount: Int) {
|
||||
val chaptersToDownload = presenter.getUnreadChaptersSorted().take(amount)
|
||||
if (chaptersToDownload.isNotEmpty()) {
|
||||
viewScope.launch { downloadChapters(chaptersToDownload) }
|
||||
}
|
||||
}
|
||||
|
||||
// Chapters list - end
|
||||
|
||||
// Tracker sheet - start
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Immutable
|
||||
import eu.kanade.core.prefs.CheckboxState
|
||||
import eu.kanade.core.prefs.mapAsCheckboxState
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||
import eu.kanade.domain.category.model.Category
|
||||
@@ -61,6 +63,7 @@ import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import logcat.LogPriority
|
||||
@@ -78,6 +81,7 @@ class MangaPresenter(
|
||||
val isFromSource: Boolean,
|
||||
private val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val trackManager: TrackManager = Injekt.get(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val getMangaAndChapters: GetMangaWithChapters = Injekt.get(),
|
||||
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
|
||||
@@ -182,6 +186,7 @@ class MangaPresenter(
|
||||
isRefreshingChapter = true,
|
||||
isIncognitoMode = incognitoMode,
|
||||
isDownloadedOnlyMode = downloadedOnlyMode,
|
||||
dialog = null,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -259,8 +264,7 @@ class MangaPresenter(
|
||||
fun toggleFavorite(
|
||||
onRemoved: () -> Unit,
|
||||
onAdded: () -> Unit,
|
||||
onRequireCategory: (manga: DomainManga, availableCats: List<Category>) -> Unit,
|
||||
onDuplicateExists: ((DomainManga) -> Unit)?,
|
||||
checkDuplicate: Boolean = true,
|
||||
) {
|
||||
val state = successState ?: return
|
||||
presenterScope.launchIO {
|
||||
@@ -278,10 +282,16 @@ class MangaPresenter(
|
||||
} else {
|
||||
// Add to library
|
||||
// First, check if duplicate exists if callback is provided
|
||||
if (onDuplicateExists != null) {
|
||||
if (checkDuplicate) {
|
||||
val duplicate = getDuplicateLibraryManga.await(manga.title, manga.source)
|
||||
|
||||
if (duplicate != null) {
|
||||
withUIContext { onDuplicateExists(duplicate) }
|
||||
_state.update { state ->
|
||||
when (state) {
|
||||
MangaScreenState.Loading -> state
|
||||
is MangaScreenState.Success -> state.copy(dialog = Dialog.DuplicateManga(manga, duplicate))
|
||||
}
|
||||
}
|
||||
return@launchIO
|
||||
}
|
||||
}
|
||||
@@ -308,7 +318,7 @@ class MangaPresenter(
|
||||
}
|
||||
|
||||
// Choose a category
|
||||
else -> withUIContext { onRequireCategory(manga, categories) }
|
||||
else -> promptChangeCategories()
|
||||
}
|
||||
|
||||
// Finally match with enhanced tracking when available
|
||||
@@ -334,6 +344,26 @@ class MangaPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
fun promptChangeCategories() {
|
||||
val state = successState ?: return
|
||||
val manga = state.manga
|
||||
presenterScope.launch {
|
||||
val categories = getCategories()
|
||||
val selection = getMangaCategoryIds(manga)
|
||||
_state.update { state ->
|
||||
when (state) {
|
||||
MangaScreenState.Loading -> state
|
||||
is MangaScreenState.Success -> state.copy(
|
||||
dialog = Dialog.ChangeCategory(
|
||||
manga = manga,
|
||||
initialSelection = categories.mapAsCheckboxState { it.id in selection },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the manga has any downloads.
|
||||
*/
|
||||
@@ -365,13 +395,13 @@ class MangaPresenter(
|
||||
* @param manga the manga to get categories from.
|
||||
* @return Array of category ids the manga is in, if none returns default id
|
||||
*/
|
||||
suspend fun getMangaCategoryIds(manga: DomainManga): Array<Long> {
|
||||
val categories = getCategories.await(manga.id)
|
||||
return categories.map { it.id }.toTypedArray()
|
||||
suspend fun getMangaCategoryIds(manga: DomainManga): List<Long> {
|
||||
return getCategories.await(manga.id)
|
||||
.map { it.id }
|
||||
}
|
||||
|
||||
fun moveMangaToCategoriesAndAddToLibrary(manga: DomainManga, categories: List<Category>) {
|
||||
moveMangaToCategories(categories)
|
||||
fun moveMangaToCategoriesAndAddToLibrary(manga: DomainManga, categories: List<Long>) {
|
||||
moveMangaToCategory(categories)
|
||||
if (!manga.favorite) {
|
||||
presenterScope.launchIO {
|
||||
updateManga.awaitUpdateFavorite(manga.id, true)
|
||||
@@ -387,6 +417,10 @@ class MangaPresenter(
|
||||
*/
|
||||
private fun moveMangaToCategories(categories: List<Category>) {
|
||||
val categoryIds = categories.map { it.id }
|
||||
moveMangaToCategory(categoryIds)
|
||||
}
|
||||
|
||||
fun moveMangaToCategory(categoryIds: List<Long>) {
|
||||
presenterScope.launchIO {
|
||||
setMangaCategories.await(mangaId, categoryIds)
|
||||
}
|
||||
@@ -994,6 +1028,45 @@ class MangaPresenter(
|
||||
}
|
||||
|
||||
// Track sheet - end
|
||||
|
||||
fun getSourceOrStub(manga: DomainManga): Source {
|
||||
return sourceManager.getOrStub(manga.source)
|
||||
}
|
||||
|
||||
sealed class Dialog {
|
||||
data class ChangeCategory(val manga: DomainManga, val initialSelection: List<CheckboxState<Category>>) : Dialog()
|
||||
data class DeleteChapters(val chapters: List<DomainChapter>) : Dialog()
|
||||
data class DuplicateManga(val manga: DomainManga, val duplicate: DomainManga) : Dialog()
|
||||
data class DownloadCustomAmount(val max: Int) : Dialog()
|
||||
}
|
||||
|
||||
fun dismissDialog() {
|
||||
_state.update { state ->
|
||||
when (state) {
|
||||
MangaScreenState.Loading -> state
|
||||
is MangaScreenState.Success -> state.copy(dialog = null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showDownloadCustomDialog() {
|
||||
val max = processedChapters?.count() ?: return
|
||||
_state.update { state ->
|
||||
when (state) {
|
||||
MangaScreenState.Loading -> state
|
||||
is MangaScreenState.Success -> state.copy(dialog = Dialog.DownloadCustomAmount(max))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showDeleteChapterDialog(chapters: List<DomainChapter>) {
|
||||
_state.update { state ->
|
||||
when (state) {
|
||||
MangaScreenState.Loading -> state
|
||||
is MangaScreenState.Success -> state.copy(dialog = Dialog.DeleteChapters(chapters))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class MangaScreenState {
|
||||
@@ -1012,6 +1085,7 @@ sealed class MangaScreenState {
|
||||
val isRefreshingChapter: Boolean = false,
|
||||
val isIncognitoMode: Boolean = false,
|
||||
val isDownloadedOnlyMode: Boolean = false,
|
||||
val dialog: MangaPresenter.Dialog? = null,
|
||||
) : MangaScreenState() {
|
||||
|
||||
val processedChapters: Sequence<ChapterItem>
|
||||
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.manga.chapter
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.core.os.bundleOf
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.widget.DialogCustomDownloadView
|
||||
|
||||
/**
|
||||
* Dialog used to let user select amount of chapters to download.
|
||||
*/
|
||||
class DownloadCustomChaptersDialog<T> : DialogController
|
||||
where T : Controller, T : DownloadCustomChaptersDialog.Listener {
|
||||
|
||||
/**
|
||||
* Maximum number of chapters to download in download chooser.
|
||||
*/
|
||||
private val maxChapters: Int
|
||||
|
||||
/**
|
||||
* Initialize dialog.
|
||||
* @param maxChapters maximal number of chapters that user can download.
|
||||
*/
|
||||
constructor(target: T, maxChapters: Int) : super(
|
||||
// Add maximum number of chapters to download value to bundle.
|
||||
bundleOf(KEY_ITEM_MAX to maxChapters),
|
||||
) {
|
||||
targetController = target
|
||||
this.maxChapters = maxChapters
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore dialog.
|
||||
* @param bundle bundle containing data from state restore.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : super(bundle) {
|
||||
// Get maximum chapters to download from bundle
|
||||
val maxChapters = bundle.getInt(KEY_ITEM_MAX, 0)
|
||||
this.maxChapters = maxChapters
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when dialog is being created.
|
||||
*/
|
||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||
val activity = activity!!
|
||||
|
||||
// Initialize view that lets user select number of chapters to download.
|
||||
val view = DialogCustomDownloadView(activity).apply {
|
||||
setMinMax(0, maxChapters)
|
||||
}
|
||||
|
||||
// Build dialog.
|
||||
// when positive dialog is pressed call custom listener.
|
||||
return MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.custom_download)
|
||||
.setView(view)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
(targetController as? Listener)?.downloadCustomChapters(view.amount)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create()
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun downloadCustomChapters(amount: Int)
|
||||
}
|
||||
}
|
||||
|
||||
// Key to retrieve max chapters from bundle on process death.
|
||||
private const val KEY_ITEM_MAX = "DownloadCustomChaptersDialog.int.maxChapters"
|
||||
Reference in New Issue
Block a user