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.Modifier
|
||||
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.presentation.category.visualName
|
||||
import eu.kanade.presentation.util.horizontalPadding
|
||||
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
|
||||
fun ChangeCategoryDialog(
|
||||
categories: List<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>>,
|
||||
initialSelection: List<CheckboxState<Category>>,
|
||||
onDismissRequest: () -> Unit,
|
||||
onEditCategories: () -> Unit,
|
||||
onConfirm: (List<Long>, List<Long>) -> Unit,
|
||||
) {
|
||||
if (categories.isEmpty()) {
|
||||
if (initialSelection.isEmpty()) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
confirmButton = {
|
||||
@ -128,12 +70,12 @@ fun ChangeCategoryDialog(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onConfirm(
|
||||
selection.filter { it is Checkbox.State.Checked || it is Checkbox.TriState.Include }.map { it.value.id },
|
||||
selection.filter { it is Checkbox.TriState.Exclude }.map { it.value.id },
|
||||
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 = "Add")
|
||||
Text(text = stringResource(id = R.string.action_add))
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -146,7 +88,7 @@ fun ChangeCategoryDialog(
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val onCheckboxChange: (Checkbox<Category>) -> Unit = {
|
||||
val onCheckboxChange: (CheckboxState<Category>) -> Unit = {
|
||||
val index = selection.indexOf(it)
|
||||
val mutableList = selection.toMutableList()
|
||||
mutableList.removeAt(index)
|
||||
@ -154,15 +96,15 @@ fun ChangeCategoryDialog(
|
||||
selection = mutableList.toList()
|
||||
}
|
||||
when (checkbox) {
|
||||
is Checkbox.TriState -> {
|
||||
is CheckboxState.TriState -> {
|
||||
TriStateCheckbox(
|
||||
state = checkbox.asState(),
|
||||
onClick = { onCheckboxChange(checkbox) },
|
||||
)
|
||||
}
|
||||
is Checkbox.State -> {
|
||||
is CheckboxState.State -> {
|
||||
Checkbox(
|
||||
checked = checkbox is Checkbox.State.Checked,
|
||||
checked = checkbox.isChecked,
|
||||
onCheckedChange = { onCheckboxChange(checkbox) },
|
||||
)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import eu.kanade.presentation.components.Checkbox
|
||||
import eu.kanade.core.prefs.CheckboxState
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
@Composable
|
||||
@ -24,10 +24,10 @@ fun DeleteLibraryMangaDialog(
|
||||
) {
|
||||
var list by remember {
|
||||
mutableStateOf(
|
||||
buildList<Checkbox.State<Int>> {
|
||||
add(Checkbox.State.None(R.string.manga_from_library))
|
||||
if (containsLocalManga) {
|
||||
add(Checkbox.State.None(R.string.downloaded_chapters))
|
||||
buildList<CheckboxState.State<Int>> {
|
||||
add(CheckboxState.State.None(R.string.manga_from_library))
|
||||
if (!containsLocalManga) {
|
||||
add(CheckboxState.State.None(R.string.downloaded_chapters))
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -44,8 +44,8 @@ fun DeleteLibraryMangaDialog(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onConfirm(
|
||||
list[0] is Checkbox.State.Checked,
|
||||
list.getOrElse(1) { Checkbox.State.None(0) } is Checkbox.State.Checked,
|
||||
list[0].isChecked,
|
||||
list.getOrElse(1) { CheckboxState.State.None(0) }.isChecked,
|
||||
)
|
||||
},
|
||||
) {
|
||||
@ -60,12 +60,12 @@ fun DeleteLibraryMangaDialog(
|
||||
list.forEach { state ->
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Checkbox(
|
||||
checked = state is Checkbox.State.Checked,
|
||||
checked = state.isChecked,
|
||||
onCheckedChange = {
|
||||
val index = list.indexOf(state)
|
||||
val mutableList = list.toMutableList()
|
||||
mutableList.removeAt(index)
|
||||
mutableList.add(index, state.next() as Checkbox.State<Int>)
|
||||
mutableList.add(index, state.next() as CheckboxState.State<Int>)
|
||||
list = mutableList.toList()
|
||||
},
|
||||
)
|
||||
|
@ -8,10 +8,11 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
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.toDbManga
|
||||
import eu.kanade.presentation.components.ChangeCategoryDialog
|
||||
import eu.kanade.presentation.components.Checkbox
|
||||
import eu.kanade.presentation.library.LibraryScreen
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
@ -67,22 +68,21 @@ class LibraryController(
|
||||
when (val dialog = presenter.dialog) {
|
||||
is LibraryPresenter.Dialog.ChangeCategory -> {
|
||||
ChangeCategoryDialog(
|
||||
categories = dialog.categories,
|
||||
initialSelection = dialog.initialSelection,
|
||||
onDismissRequest = onDismissRequest,
|
||||
onEditCategories = {
|
||||
router.popCurrentController()
|
||||
presenter.clearSelection()
|
||||
router.pushController(CategoryController())
|
||||
},
|
||||
onConfirm = { include, exclude ->
|
||||
presenter.setMangaCategories(dialog.manga, include, exclude)
|
||||
presenter.clearSelection()
|
||||
presenter.setMangaCategories(dialog.manga, include, exclude)
|
||||
},
|
||||
)
|
||||
}
|
||||
is LibraryPresenter.Dialog.DeleteManga -> {
|
||||
DeleteLibraryMangaDialog(
|
||||
containsLocalManga = dialog.manga.any { !it.isLocal() },
|
||||
containsLocalManga = dialog.manga.any(Manga::isLocal),
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirm = { deleteManga, deleteChapter ->
|
||||
presenter.removeMangas(dialog.manga.map { it.toDbManga() }, deleteManga, deleteChapter)
|
||||
@ -197,40 +197,40 @@ class LibraryController(
|
||||
private fun showMangaCategoriesDialog() {
|
||||
viewScope.launchIO {
|
||||
// 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.
|
||||
val categories = presenter.categories.filter { it.id != 0L }
|
||||
|
||||
// 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.
|
||||
val mix = presenter.getMixCategories(manga)
|
||||
val mix = presenter.getMixCategories(mangaList)
|
||||
val preselected = categories.map {
|
||||
when (it) {
|
||||
in common -> Checkbox.State.Checked(it)
|
||||
in mix -> Checkbox.TriState.Exclude(it)
|
||||
else -> Checkbox.State.None(it)
|
||||
in common -> CheckboxState.State.Checked(it)
|
||||
in mix -> CheckboxState.TriState.Exclude(it)
|
||||
else -> CheckboxState.State.None(it)
|
||||
}
|
||||
}
|
||||
presenter.dialog = LibraryPresenter.Dialog.ChangeCategory(manga, categories, preselected)
|
||||
presenter.dialog = LibraryPresenter.Dialog.ChangeCategory(mangaList, preselected)
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadUnreadChapters() {
|
||||
val manga = presenter.selection.toList()
|
||||
presenter.downloadUnreadChapters(manga.mapNotNull { it.toDomainManga() })
|
||||
val mangaList = presenter.selection.toList()
|
||||
presenter.downloadUnreadChapters(mangaList.mapNotNull { it.toDomainManga() })
|
||||
presenter.clearSelection()
|
||||
}
|
||||
|
||||
private fun markReadStatus(read: Boolean) {
|
||||
val manga = presenter.selection.toList()
|
||||
presenter.markReadStatus(manga.mapNotNull { it.toDomainManga() }, read)
|
||||
val mangaList = presenter.selection.toList()
|
||||
presenter.markReadStatus(mangaList.mapNotNull { it.toDomainManga() }, read)
|
||||
presenter.clearSelection()
|
||||
}
|
||||
|
||||
private fun showDeleteMangaDialog() {
|
||||
val manga = presenter.selection.mapNotNull { it.toDomainManga() }.toList()
|
||||
presenter.dialog = LibraryPresenter.Dialog.DeleteManga(manga)
|
||||
val mangaList = presenter.selection.mapNotNull { it.toDomainManga() }.toList()
|
||||
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.util.fastAny
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.core.prefs.CheckboxState
|
||||
import eu.kanade.core.prefs.PreferenceMutableState
|
||||
import eu.kanade.core.util.asFlow
|
||||
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.track.interactor.GetTracks
|
||||
import eu.kanade.presentation.category.visualName
|
||||
import eu.kanade.presentation.components.Checkbox
|
||||
import eu.kanade.presentation.library.LibraryState
|
||||
import eu.kanade.presentation.library.LibraryStateImpl
|
||||
import eu.kanade.presentation.library.components.LibraryToolbarTitle
|
||||
@ -720,7 +720,7 @@ class LibraryPresenter(
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
@ -151,15 +151,13 @@ class MangaController : FullComposeController<MangaPresenter> {
|
||||
when (val dialog = dialog) {
|
||||
is Dialog.ChangeCategory -> {
|
||||
ChangeCategoryDialog(
|
||||
categories = dialog.categories,
|
||||
initialSelection = dialog.initialSelection,
|
||||
onDismissRequest = onDismissRequest,
|
||||
onEditCategories = {
|
||||
router.popCurrentController()
|
||||
router.pushController(CategoryController())
|
||||
},
|
||||
onConfirm = {
|
||||
presenter.moveMangaToCategoriesAndAddToLibrary(dialog.manga, it)
|
||||
onConfirm = { include, _ ->
|
||||
presenter.moveMangaToCategoriesAndAddToLibrary(dialog.manga, include)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -186,7 +184,13 @@ class MangaController : FullComposeController<MangaPresenter> {
|
||||
is Dialog.DuplicateManga -> {
|
||||
DuplicateDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirm = { presenter.toggleFavorite({}, {}, false) },
|
||||
onConfirm = {
|
||||
presenter.toggleFavorite(
|
||||
onRemoved = {},
|
||||
onAdded = {},
|
||||
checkDuplicate = false,
|
||||
)
|
||||
},
|
||||
onOpenManga = { router.pushController(MangaController(dialog.duplicate.id)) },
|
||||
duplicateFrom = presenter.getSourceOrStub(dialog.duplicate),
|
||||
)
|
||||
|
@ -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
|
||||
@ -347,10 +349,16 @@ class MangaPresenter(
|
||||
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, 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 {
|
||||
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 DuplicateManga(val manga: DomainManga, val duplicate: DomainManga) : 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