Review changes
This commit is contained in:
parent
6d14225644
commit
96e3c60923
55
app/src/main/java/eu/kanade/core/prefs/CheckboxState.kt
Normal file
55
app/src/main/java/eu/kanade/core/prefs/CheckboxState.kt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package eu.kanade.core.prefs
|
||||||
|
|
||||||
|
import androidx.compose.ui.state.ToggleableState
|
||||||
|
|
||||||
|
sealed class CheckboxState<T>(open val value: T) {
|
||||||
|
abstract fun next(): CheckboxState<T>
|
||||||
|
|
||||||
|
sealed class State<T>(override val value: T) : CheckboxState<T>(value) {
|
||||||
|
data class Checked<T>(override val value: T) : State<T>(value)
|
||||||
|
data class None<T>(override val value: T) : State<T>(value)
|
||||||
|
|
||||||
|
val isChecked: Boolean
|
||||||
|
get() = this is Checked
|
||||||
|
|
||||||
|
override fun next(): CheckboxState<T> {
|
||||||
|
return when (this) {
|
||||||
|
is Checked -> None(value)
|
||||||
|
is None -> Checked(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sealed class TriState<T>(override val value: T) : CheckboxState<T>(value) {
|
||||||
|
data class Include<T>(override val value: T) : TriState<T>(value)
|
||||||
|
data class Exclude<T>(override val value: T) : TriState<T>(value)
|
||||||
|
data class None<T>(override val value: T) : TriState<T>(value)
|
||||||
|
|
||||||
|
override fun next(): CheckboxState<T> {
|
||||||
|
return when (this) {
|
||||||
|
is Exclude -> None(value)
|
||||||
|
is Include -> Exclude(value)
|
||||||
|
is None -> Include(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun asState(): ToggleableState {
|
||||||
|
return when (this) {
|
||||||
|
is Exclude -> ToggleableState.Indeterminate
|
||||||
|
is Include -> ToggleableState.On
|
||||||
|
is None -> ToggleableState.Off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> T.asCheckboxState(condition: (T) -> Boolean): CheckboxState.State<T> {
|
||||||
|
return if (condition(this)) {
|
||||||
|
CheckboxState.State.Checked(this)
|
||||||
|
} else {
|
||||||
|
CheckboxState.State.None(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> List<T>.mapAsCheckboxState(condition: (T) -> Boolean): List<CheckboxState.State<T>> {
|
||||||
|
return this.map { it.asCheckboxState(condition) }
|
||||||
|
}
|
@ -16,78 +16,20 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.state.ToggleableState
|
import eu.kanade.core.prefs.CheckboxState
|
||||||
import eu.kanade.domain.category.model.Category
|
import eu.kanade.domain.category.model.Category
|
||||||
import eu.kanade.presentation.category.visualName
|
import eu.kanade.presentation.category.visualName
|
||||||
import eu.kanade.presentation.util.horizontalPadding
|
import eu.kanade.presentation.util.horizontalPadding
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
sealed class Checkbox<T>(open val value: T) {
|
|
||||||
abstract fun next(): Checkbox<T>
|
|
||||||
|
|
||||||
sealed class State<T>(override val value: T) : Checkbox<T>(value) {
|
|
||||||
data class Checked<T>(override val value: T) : State<T>(value)
|
|
||||||
data class None<T>(override val value: T) : State<T>(value)
|
|
||||||
|
|
||||||
override fun next(): Checkbox<T> {
|
|
||||||
return when (this) {
|
|
||||||
is Checked -> None(value)
|
|
||||||
is None -> Checked(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sealed class TriState<T>(override val value: T) : Checkbox<T>(value) {
|
|
||||||
data class Include<T>(override val value: T) : TriState<T>(value)
|
|
||||||
data class Exclude<T>(override val value: T) : TriState<T>(value)
|
|
||||||
data class None<T>(override val value: T) : TriState<T>(value)
|
|
||||||
|
|
||||||
override fun next(): Checkbox<T> {
|
|
||||||
return when (this) {
|
|
||||||
is Exclude -> None(value)
|
|
||||||
is Include -> Exclude(value)
|
|
||||||
is None -> Include(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun asState(): ToggleableState {
|
|
||||||
return when (this) {
|
|
||||||
is Exclude -> ToggleableState.Indeterminate
|
|
||||||
is Include -> ToggleableState.On
|
|
||||||
is None -> ToggleableState.Off
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("ChangeCategoryDialogHelper")
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChangeCategoryDialog(
|
fun ChangeCategoryDialog(
|
||||||
categories: List<Category>,
|
initialSelection: List<CheckboxState<Category>>,
|
||||||
initialSelection: List<Long>,
|
|
||||||
onDismissRequest: () -> Unit,
|
|
||||||
onEditCategories: () -> Unit,
|
|
||||||
onConfirm: (List<Long>) -> Unit,
|
|
||||||
) {
|
|
||||||
ChangeCategoryDialog(
|
|
||||||
categories = categories,
|
|
||||||
initialSelection = categories.map {
|
|
||||||
if (it.id in initialSelection) Checkbox.State.Checked(it) else Checkbox.State.None(it)
|
|
||||||
},
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
onEditCategories = onEditCategories,
|
|
||||||
onConfirm = { include, _ -> onConfirm(include.map { it }) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ChangeCategoryDialog(
|
|
||||||
categories: List<Category>,
|
|
||||||
initialSelection: List<Checkbox<Category>>,
|
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onEditCategories: () -> Unit,
|
onEditCategories: () -> Unit,
|
||||||
onConfirm: (List<Long>, List<Long>) -> Unit,
|
onConfirm: (List<Long>, List<Long>) -> Unit,
|
||||||
) {
|
) {
|
||||||
if (categories.isEmpty()) {
|
if (initialSelection.isEmpty()) {
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
@ -128,12 +70,12 @@ fun ChangeCategoryDialog(
|
|||||||
onClick = {
|
onClick = {
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
onConfirm(
|
onConfirm(
|
||||||
selection.filter { it is Checkbox.State.Checked || it is Checkbox.TriState.Include }.map { it.value.id },
|
selection.filter { it is CheckboxState.State.Checked || it is CheckboxState.TriState.Include }.map { it.value.id },
|
||||||
selection.filter { it is Checkbox.TriState.Exclude }.map { it.value.id },
|
selection.filter { it is CheckboxState.TriState.Exclude }.map { it.value.id },
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Text(text = "Add")
|
Text(text = stringResource(id = R.string.action_add))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -146,7 +88,7 @@ fun ChangeCategoryDialog(
|
|||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
val onCheckboxChange: (Checkbox<Category>) -> Unit = {
|
val onCheckboxChange: (CheckboxState<Category>) -> Unit = {
|
||||||
val index = selection.indexOf(it)
|
val index = selection.indexOf(it)
|
||||||
val mutableList = selection.toMutableList()
|
val mutableList = selection.toMutableList()
|
||||||
mutableList.removeAt(index)
|
mutableList.removeAt(index)
|
||||||
@ -154,15 +96,15 @@ fun ChangeCategoryDialog(
|
|||||||
selection = mutableList.toList()
|
selection = mutableList.toList()
|
||||||
}
|
}
|
||||||
when (checkbox) {
|
when (checkbox) {
|
||||||
is Checkbox.TriState -> {
|
is CheckboxState.TriState -> {
|
||||||
TriStateCheckbox(
|
TriStateCheckbox(
|
||||||
state = checkbox.asState(),
|
state = checkbox.asState(),
|
||||||
onClick = { onCheckboxChange(checkbox) },
|
onClick = { onCheckboxChange(checkbox) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Checkbox.State -> {
|
is CheckboxState.State -> {
|
||||||
Checkbox(
|
Checkbox(
|
||||||
checked = checkbox is Checkbox.State.Checked,
|
checked = checkbox.isChecked,
|
||||||
onCheckedChange = { onCheckboxChange(checkbox) },
|
onCheckedChange = { onCheckboxChange(checkbox) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.presentation.components.Checkbox
|
import eu.kanade.core.prefs.CheckboxState
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -24,10 +24,10 @@ fun DeleteLibraryMangaDialog(
|
|||||||
) {
|
) {
|
||||||
var list by remember {
|
var list by remember {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
buildList<Checkbox.State<Int>> {
|
buildList<CheckboxState.State<Int>> {
|
||||||
add(Checkbox.State.None(R.string.manga_from_library))
|
add(CheckboxState.State.None(R.string.manga_from_library))
|
||||||
if (containsLocalManga) {
|
if (!containsLocalManga) {
|
||||||
add(Checkbox.State.None(R.string.downloaded_chapters))
|
add(CheckboxState.State.None(R.string.downloaded_chapters))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -44,8 +44,8 @@ fun DeleteLibraryMangaDialog(
|
|||||||
onClick = {
|
onClick = {
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
onConfirm(
|
onConfirm(
|
||||||
list[0] is Checkbox.State.Checked,
|
list[0].isChecked,
|
||||||
list.getOrElse(1) { Checkbox.State.None(0) } is Checkbox.State.Checked,
|
list.getOrElse(1) { CheckboxState.State.None(0) }.isChecked,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@ -60,12 +60,12 @@ fun DeleteLibraryMangaDialog(
|
|||||||
list.forEach { state ->
|
list.forEach { state ->
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Checkbox(
|
Checkbox(
|
||||||
checked = state is Checkbox.State.Checked,
|
checked = state.isChecked,
|
||||||
onCheckedChange = {
|
onCheckedChange = {
|
||||||
val index = list.indexOf(state)
|
val index = list.indexOf(state)
|
||||||
val mutableList = list.toMutableList()
|
val mutableList = list.toMutableList()
|
||||||
mutableList.removeAt(index)
|
mutableList.removeAt(index)
|
||||||
mutableList.add(index, state.next() as Checkbox.State<Int>)
|
mutableList.add(index, state.next() as CheckboxState.State<Int>)
|
||||||
list = mutableList.toList()
|
list = mutableList.toList()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -8,10 +8,11 @@ import androidx.compose.runtime.LaunchedEffect
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
|
import eu.kanade.core.prefs.CheckboxState
|
||||||
|
import eu.kanade.domain.manga.model.Manga
|
||||||
import eu.kanade.domain.manga.model.isLocal
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
import eu.kanade.domain.manga.model.toDbManga
|
import eu.kanade.domain.manga.model.toDbManga
|
||||||
import eu.kanade.presentation.components.ChangeCategoryDialog
|
import eu.kanade.presentation.components.ChangeCategoryDialog
|
||||||
import eu.kanade.presentation.components.Checkbox
|
|
||||||
import eu.kanade.presentation.library.LibraryScreen
|
import eu.kanade.presentation.library.LibraryScreen
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||||
@ -67,22 +68,21 @@ class LibraryController(
|
|||||||
when (val dialog = presenter.dialog) {
|
when (val dialog = presenter.dialog) {
|
||||||
is LibraryPresenter.Dialog.ChangeCategory -> {
|
is LibraryPresenter.Dialog.ChangeCategory -> {
|
||||||
ChangeCategoryDialog(
|
ChangeCategoryDialog(
|
||||||
categories = dialog.categories,
|
|
||||||
initialSelection = dialog.initialSelection,
|
initialSelection = dialog.initialSelection,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
onEditCategories = {
|
onEditCategories = {
|
||||||
router.popCurrentController()
|
presenter.clearSelection()
|
||||||
router.pushController(CategoryController())
|
router.pushController(CategoryController())
|
||||||
},
|
},
|
||||||
onConfirm = { include, exclude ->
|
onConfirm = { include, exclude ->
|
||||||
presenter.setMangaCategories(dialog.manga, include, exclude)
|
|
||||||
presenter.clearSelection()
|
presenter.clearSelection()
|
||||||
|
presenter.setMangaCategories(dialog.manga, include, exclude)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is LibraryPresenter.Dialog.DeleteManga -> {
|
is LibraryPresenter.Dialog.DeleteManga -> {
|
||||||
DeleteLibraryMangaDialog(
|
DeleteLibraryMangaDialog(
|
||||||
containsLocalManga = dialog.manga.any { !it.isLocal() },
|
containsLocalManga = dialog.manga.any(Manga::isLocal),
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
onConfirm = { deleteManga, deleteChapter ->
|
onConfirm = { deleteManga, deleteChapter ->
|
||||||
presenter.removeMangas(dialog.manga.map { it.toDbManga() }, deleteManga, deleteChapter)
|
presenter.removeMangas(dialog.manga.map { it.toDbManga() }, deleteManga, deleteChapter)
|
||||||
@ -197,40 +197,40 @@ class LibraryController(
|
|||||||
private fun showMangaCategoriesDialog() {
|
private fun showMangaCategoriesDialog() {
|
||||||
viewScope.launchIO {
|
viewScope.launchIO {
|
||||||
// Create a copy of selected manga
|
// Create a copy of selected manga
|
||||||
val manga = presenter.selection.mapNotNull { it.toDomainManga() }.toList()
|
val mangaList = presenter.selection.mapNotNull { it.toDomainManga() }.toList()
|
||||||
|
|
||||||
// Hide the default category because it has a different behavior than the ones from db.
|
// Hide the default category because it has a different behavior than the ones from db.
|
||||||
val categories = presenter.categories.filter { it.id != 0L }
|
val categories = presenter.categories.filter { it.id != 0L }
|
||||||
|
|
||||||
// Get indexes of the common categories to preselect.
|
// Get indexes of the common categories to preselect.
|
||||||
val common = presenter.getCommonCategories(manga)
|
val common = presenter.getCommonCategories(mangaList)
|
||||||
// Get indexes of the mix categories to preselect.
|
// Get indexes of the mix categories to preselect.
|
||||||
val mix = presenter.getMixCategories(manga)
|
val mix = presenter.getMixCategories(mangaList)
|
||||||
val preselected = categories.map {
|
val preselected = categories.map {
|
||||||
when (it) {
|
when (it) {
|
||||||
in common -> Checkbox.State.Checked(it)
|
in common -> CheckboxState.State.Checked(it)
|
||||||
in mix -> Checkbox.TriState.Exclude(it)
|
in mix -> CheckboxState.TriState.Exclude(it)
|
||||||
else -> Checkbox.State.None(it)
|
else -> CheckboxState.State.None(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
presenter.dialog = LibraryPresenter.Dialog.ChangeCategory(manga, categories, preselected)
|
presenter.dialog = LibraryPresenter.Dialog.ChangeCategory(mangaList, preselected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadUnreadChapters() {
|
private fun downloadUnreadChapters() {
|
||||||
val manga = presenter.selection.toList()
|
val mangaList = presenter.selection.toList()
|
||||||
presenter.downloadUnreadChapters(manga.mapNotNull { it.toDomainManga() })
|
presenter.downloadUnreadChapters(mangaList.mapNotNull { it.toDomainManga() })
|
||||||
presenter.clearSelection()
|
presenter.clearSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markReadStatus(read: Boolean) {
|
private fun markReadStatus(read: Boolean) {
|
||||||
val manga = presenter.selection.toList()
|
val mangaList = presenter.selection.toList()
|
||||||
presenter.markReadStatus(manga.mapNotNull { it.toDomainManga() }, read)
|
presenter.markReadStatus(mangaList.mapNotNull { it.toDomainManga() }, read)
|
||||||
presenter.clearSelection()
|
presenter.clearSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showDeleteMangaDialog() {
|
private fun showDeleteMangaDialog() {
|
||||||
val manga = presenter.selection.mapNotNull { it.toDomainManga() }.toList()
|
val mangaList = presenter.selection.mapNotNull { it.toDomainManga() }.toList()
|
||||||
presenter.dialog = LibraryPresenter.Dialog.DeleteManga(manga)
|
presenter.dialog = LibraryPresenter.Dialog.DeleteManga(mangaList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.util.fastAny
|
import androidx.compose.ui.util.fastAny
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
|
import eu.kanade.core.prefs.CheckboxState
|
||||||
import eu.kanade.core.prefs.PreferenceMutableState
|
import eu.kanade.core.prefs.PreferenceMutableState
|
||||||
import eu.kanade.core.util.asFlow
|
import eu.kanade.core.util.asFlow
|
||||||
import eu.kanade.core.util.asObservable
|
import eu.kanade.core.util.asObservable
|
||||||
@ -28,7 +29,6 @@ import eu.kanade.domain.manga.model.MangaUpdate
|
|||||||
import eu.kanade.domain.manga.model.isLocal
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
import eu.kanade.domain.track.interactor.GetTracks
|
import eu.kanade.domain.track.interactor.GetTracks
|
||||||
import eu.kanade.presentation.category.visualName
|
import eu.kanade.presentation.category.visualName
|
||||||
import eu.kanade.presentation.components.Checkbox
|
|
||||||
import eu.kanade.presentation.library.LibraryState
|
import eu.kanade.presentation.library.LibraryState
|
||||||
import eu.kanade.presentation.library.LibraryStateImpl
|
import eu.kanade.presentation.library.LibraryStateImpl
|
||||||
import eu.kanade.presentation.library.components.LibraryToolbarTitle
|
import eu.kanade.presentation.library.components.LibraryToolbarTitle
|
||||||
@ -720,7 +720,7 @@ class LibraryPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed class Dialog {
|
||||||
data class ChangeCategory(val manga: List<Manga>, val categories: List<Category>, val initialSelection: List<Checkbox<Category>>) : Dialog()
|
data class ChangeCategory(val manga: List<Manga>, val initialSelection: List<CheckboxState<Category>>) : Dialog()
|
||||||
data class DeleteManga(val manga: List<Manga>) : Dialog()
|
data class DeleteManga(val manga: List<Manga>) : Dialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,15 +151,13 @@ class MangaController : FullComposeController<MangaPresenter> {
|
|||||||
when (val dialog = dialog) {
|
when (val dialog = dialog) {
|
||||||
is Dialog.ChangeCategory -> {
|
is Dialog.ChangeCategory -> {
|
||||||
ChangeCategoryDialog(
|
ChangeCategoryDialog(
|
||||||
categories = dialog.categories,
|
|
||||||
initialSelection = dialog.initialSelection,
|
initialSelection = dialog.initialSelection,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
onEditCategories = {
|
onEditCategories = {
|
||||||
router.popCurrentController()
|
|
||||||
router.pushController(CategoryController())
|
router.pushController(CategoryController())
|
||||||
},
|
},
|
||||||
onConfirm = {
|
onConfirm = { include, _ ->
|
||||||
presenter.moveMangaToCategoriesAndAddToLibrary(dialog.manga, it)
|
presenter.moveMangaToCategoriesAndAddToLibrary(dialog.manga, include)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -186,7 +184,13 @@ class MangaController : FullComposeController<MangaPresenter> {
|
|||||||
is Dialog.DuplicateManga -> {
|
is Dialog.DuplicateManga -> {
|
||||||
DuplicateDialog(
|
DuplicateDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
onConfirm = { presenter.toggleFavorite({}, {}, false) },
|
onConfirm = {
|
||||||
|
presenter.toggleFavorite(
|
||||||
|
onRemoved = {},
|
||||||
|
onAdded = {},
|
||||||
|
checkDuplicate = false,
|
||||||
|
)
|
||||||
|
},
|
||||||
onOpenManga = { router.pushController(MangaController(dialog.duplicate.id)) },
|
onOpenManga = { router.pushController(MangaController(dialog.duplicate.id)) },
|
||||||
duplicateFrom = presenter.getSourceOrStub(dialog.duplicate),
|
duplicateFrom = presenter.getSourceOrStub(dialog.duplicate),
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,8 @@ import android.app.Application
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.compose.runtime.Immutable
|
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.GetCategories
|
||||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||||
import eu.kanade.domain.category.model.Category
|
import eu.kanade.domain.category.model.Category
|
||||||
@ -347,10 +349,16 @@ class MangaPresenter(
|
|||||||
val manga = state.manga
|
val manga = state.manga
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
val categories = getCategories()
|
val categories = getCategories()
|
||||||
|
val selection = getMangaCategoryIds(manga)
|
||||||
_state.update { state ->
|
_state.update { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
MangaScreenState.Loading -> state
|
MangaScreenState.Loading -> state
|
||||||
is MangaScreenState.Success -> state.copy(dialog = Dialog.ChangeCategory(manga, categories, getMangaCategoryIds(manga)))
|
is MangaScreenState.Success -> state.copy(
|
||||||
|
dialog = Dialog.ChangeCategory(
|
||||||
|
manga = manga,
|
||||||
|
initialSelection = categories.mapAsCheckboxState { it.id in selection },
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1026,7 +1034,7 @@ class MangaPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed class Dialog {
|
||||||
data class ChangeCategory(val manga: DomainManga, val categories: List<Category>, val initialSelection: List<Long>) : Dialog()
|
data class ChangeCategory(val manga: DomainManga, val initialSelection: List<CheckboxState<Category>>) : Dialog()
|
||||||
data class DeleteChapters(val chapters: List<DomainChapter>) : Dialog()
|
data class DeleteChapters(val chapters: List<DomainChapter>) : Dialog()
|
||||||
data class DuplicateManga(val manga: DomainManga, val duplicate: DomainManga) : Dialog()
|
data class DuplicateManga(val manga: DomainManga, val duplicate: DomainManga) : Dialog()
|
||||||
data class DownloadCustomAmount(val max: Int) : Dialog()
|
data class DownloadCustomAmount(val max: Int) : Dialog()
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/black"
|
|
||||||
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" />
|
|
||||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/black"
|
|
||||||
android:pathData="M18.41,7.41L17,6L11,12L17,18L18.41,16.59L13.83,12L18.41,7.41M12.41,7.41L11,6L5,12L11,18L12.41,16.59L7.83,12L12.41,7.41Z" />
|
|
||||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/black"
|
|
||||||
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
|
|
||||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/black"
|
|
||||||
android:pathData="M5.59,7.41L7,6L13,12L7,18L5.59,16.59L10.17,12L5.59,7.41M11.59,7.41L13,6L19,12L13,18L11.59,16.59L16.17,12L11.59,7.41Z" />
|
|
||||||
</vector>
|
|
@ -1,47 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingVertical="8dp">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
style="@style/Widget.Tachiyomi.Button.IconButton"
|
|
||||||
android:id="@+id/btn_decrease_10"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:icon="@drawable/ic_chevron_left_double_black_24dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
style="@style/Widget.Tachiyomi.Button.IconButton"
|
|
||||||
android:id="@+id/btn_decrease"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:icon="@drawable/ic_chevron_left_black_24dp" />
|
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText
|
|
||||||
android:id="@+id/myNumber"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:digits="0123456789"
|
|
||||||
android:inputType="number"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
style="@style/Widget.Tachiyomi.Button.IconButton"
|
|
||||||
android:id="@+id/btn_increase"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:icon="@drawable/ic_chevron_right_black_24dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
style="@style/Widget.Tachiyomi.Button.IconButton"
|
|
||||||
android:id="@+id/btn_increase_10"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:icon="@drawable/ic_chevron_right_double_black_24dp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
Loading…
x
Reference in New Issue
Block a user