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:
Andreas
2022-08-26 14:57:28 +02:00
committed by GitHub
parent 4b9a6541d1
commit 2453d1a886
20 changed files with 657 additions and 479 deletions

View File

@@ -0,0 +1,122 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Text
import androidx.compose.material3.TriStateCheckbox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.core.prefs.CheckboxState
import eu.kanade.domain.category.model.Category
import eu.kanade.presentation.category.visualName
import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.tachiyomi.R
@Composable
fun ChangeCategoryDialog(
initialSelection: List<CheckboxState<Category>>,
onDismissRequest: () -> Unit,
onEditCategories: () -> Unit,
onConfirm: (List<Long>, List<Long>) -> Unit,
) {
if (initialSelection.isEmpty()) {
AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(
onClick = {
onDismissRequest()
onEditCategories()
},
) {
Text(text = stringResource(id = R.string.action_edit_categories))
}
},
title = {
Text(text = stringResource(id = R.string.action_move_category))
},
text = {
Text(text = stringResource(id = R.string.information_empty_category_dialog))
},
)
return
}
var selection by remember { mutableStateOf(initialSelection) }
AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
Row {
TextButton(onClick = {
onDismissRequest()
onEditCategories()
},) {
Text(text = stringResource(id = R.string.action_edit))
}
Spacer(modifier = Modifier.weight(1f))
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel))
}
TextButton(
onClick = {
onDismissRequest()
onConfirm(
selection.filter { it is CheckboxState.State.Checked || it is CheckboxState.TriState.Include }.map { it.value.id },
selection.filter { it is CheckboxState.TriState.Exclude }.map { it.value.id },
)
},
) {
Text(text = stringResource(id = R.string.action_add))
}
}
},
title = {
Text(text = stringResource(id = R.string.action_move_category))
},
text = {
Column {
selection.forEach { checkbox ->
Row(
verticalAlignment = Alignment.CenterVertically,
) {
val onCheckboxChange: (CheckboxState<Category>) -> Unit = {
val index = selection.indexOf(it)
val mutableList = selection.toMutableList()
mutableList.removeAt(index)
mutableList.add(index, it.next())
selection = mutableList.toList()
}
when (checkbox) {
is CheckboxState.TriState -> {
TriStateCheckbox(
state = checkbox.asState(),
onClick = { onCheckboxChange(checkbox) },
)
}
is CheckboxState.State -> {
Checkbox(
checked = checkbox.isChecked,
onCheckedChange = { onCheckboxChange(checkbox) },
)
}
}
Text(
text = checkbox.value.visualName,
modifier = Modifier.padding(horizontal = horizontalPadding),
)
}
}
}
},
)
}

View File

@@ -0,0 +1,78 @@
package eu.kanade.tachiyomi.ui.library
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.stringResource
import eu.kanade.core.prefs.CheckboxState
import eu.kanade.tachiyomi.R
@Composable
fun DeleteLibraryMangaDialog(
containsLocalManga: Boolean,
onDismissRequest: () -> Unit,
onConfirm: (Boolean, Boolean) -> Unit,
) {
var list by remember {
mutableStateOf(
buildList<CheckboxState.State<Int>> {
add(CheckboxState.State.None(R.string.manga_from_library))
if (!containsLocalManga) {
add(CheckboxState.State.None(R.string.downloaded_chapters))
}
},
)
}
AlertDialog(
onDismissRequest = onDismissRequest,
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
onDismissRequest()
onConfirm(
list[0].isChecked,
list.getOrElse(1) { CheckboxState.State.None(0) }.isChecked,
)
},
) {
Text(text = stringResource(id = android.R.string.ok))
}
},
title = {
Text(text = stringResource(id = R.string.action_remove))
},
text = {
Column {
list.forEach { state ->
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = state.isChecked,
onCheckedChange = {
val index = list.indexOf(state)
val mutableList = list.toMutableList()
mutableList.removeAt(index)
mutableList.add(index, state.next() as CheckboxState.State<Int>)
list = mutableList.toList()
},
)
Text(text = stringResource(id = state.value))
}
}
}
},
)
}

View File

@@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eu.kanade.domain.category.model.Category
import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.ui.library.LibraryPresenter
@Stable
interface LibraryState {
@@ -16,6 +17,7 @@ interface LibraryState {
val selection: List<LibraryManga>
val selectionMode: Boolean
var hasActiveFilters: Boolean
var dialog: LibraryPresenter.Dialog?
}
fun LibraryState(): LibraryState {
@@ -29,4 +31,5 @@ class LibraryStateImpl : LibraryState {
override var selection: List<LibraryManga> by mutableStateOf(emptyList())
override val selectionMode: Boolean by derivedStateOf { selection.isNotEmpty() }
override var hasActiveFilters: Boolean by mutableStateOf(false)
override var dialog: LibraryPresenter.Dialog? by mutableStateOf(null)
}

View File

@@ -0,0 +1,90 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ChevronLeft
import androidx.compose.material.icons.outlined.ChevronRight
import androidx.compose.material.icons.outlined.KeyboardDoubleArrowLeft
import androidx.compose.material.icons.outlined.KeyboardDoubleArrowRight
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import eu.kanade.tachiyomi.R
@Composable
fun DownloadCustomAmountDialog(
maxAmount: Int,
onDismissRequest: () -> Unit,
onConfirm: (Int) -> Unit,
) {
var amount by remember { mutableStateOf(0) }
AlertDialog(
onDismissRequest = onDismissRequest,
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
onDismissRequest()
onConfirm(amount.coerceIn(0, maxAmount))
},
) {
Text(text = stringResource(id = android.R.string.ok))
}
},
title = {
Text(text = stringResource(id = R.string.custom_download))
},
text = {
val onChangeAmount: (Int) -> Unit = { amount = (amount + it).coerceIn(0, maxAmount) }
Row(
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(
onClick = { onChangeAmount(-10) },
enabled = amount > 10,
) {
Icon(imageVector = Icons.Outlined.KeyboardDoubleArrowLeft, contentDescription = "")
}
IconButton(
onClick = { onChangeAmount(-1) },
enabled = amount > 0,
) {
Icon(imageVector = Icons.Outlined.ChevronLeft, contentDescription = "")
}
BasicTextField(
value = amount.toString(),
onValueChange = { onChangeAmount(it.toIntOrNull() ?: 0) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
)
IconButton(
onClick = { onChangeAmount(1) },
enabled = amount < maxAmount,
) {
Icon(imageVector = Icons.Outlined.ChevronRight, contentDescription = "")
}
IconButton(
onClick = { onChangeAmount(10) },
enabled = amount < maxAmount,
) {
Icon(imageVector = Icons.Outlined.KeyboardDoubleArrowRight, contentDescription = "")
}
}
},
)
}

View File

@@ -0,0 +1,39 @@
package eu.kanade.presentation.manga.components
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R
@Composable
fun DeleteChaptersDialog(
onDismissRequest: () -> Unit,
onConfirm: () -> Unit,
) {
AlertDialog(
onDismissRequest = onDismissRequest,
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = android.R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
onDismissRequest()
onConfirm()
},
) {
Text(text = stringResource(id = android.R.string.ok))
}
},
title = {
Text(text = stringResource(id = R.string.are_you_sure))
},
text = {
Text(text = stringResource(id = R.string.confirm_delete_chapters))
},
)
}