Pull out settings sheet items as reusable composables

(cherry picked from commit 7cbe18d325274de22b2bef30869d2cc658b72cc1)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/manga/ChapterSettingsDialog.kt
This commit is contained in:
arkon 2022-12-09 22:23:26 -05:00 committed by Jobobby04
parent 5ac5005116
commit 623f0e2612
3 changed files with 226 additions and 226 deletions

View File

@ -0,0 +1,128 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDownward
import androidx.compose.material.icons.filled.ArrowUpward
import androidx.compose.material.icons.rounded.CheckBox
import androidx.compose.material.icons.rounded.CheckBoxOutlineBlank
import androidx.compose.material.icons.rounded.DisabledByDefault
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import eu.kanade.domain.manga.model.TriStateFilter
@Composable
fun TriStateItem(
label: String,
state: TriStateFilter,
onClick: ((TriStateFilter) -> Unit)?,
) {
Row(
modifier = Modifier
.clickable(
enabled = onClick != null,
onClick = {
when (state) {
TriStateFilter.DISABLED -> onClick?.invoke(TriStateFilter.ENABLED_IS)
TriStateFilter.ENABLED_IS -> onClick?.invoke(TriStateFilter.ENABLED_NOT)
TriStateFilter.ENABLED_NOT -> onClick?.invoke(TriStateFilter.DISABLED)
}
},
)
.fillMaxWidth()
.padding(horizontal = TabbedDialogPaddings.Horizontal, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
Icon(
imageVector = when (state) {
TriStateFilter.DISABLED -> Icons.Rounded.CheckBoxOutlineBlank
TriStateFilter.ENABLED_IS -> Icons.Rounded.CheckBox
TriStateFilter.ENABLED_NOT -> Icons.Rounded.DisabledByDefault
},
contentDescription = null,
tint = if (state == TriStateFilter.DISABLED) {
MaterialTheme.colorScheme.onSurfaceVariant
} else {
MaterialTheme.colorScheme.primary
},
)
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
)
}
}
@Composable
fun SortItem(
label: String,
sortDescending: Boolean?,
onClick: () -> Unit,
) {
val arrowIcon = when (sortDescending) {
true -> Icons.Default.ArrowDownward
false -> Icons.Default.ArrowUpward
null -> null
}
Row(
modifier = Modifier
.clickable(onClick = onClick)
.fillMaxWidth()
.padding(horizontal = TabbedDialogPaddings.Horizontal, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
if (arrowIcon != null) {
Icon(
imageVector = arrowIcon,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
)
} else {
Spacer(modifier = Modifier.size(24.dp))
}
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
)
}
}
@Composable
fun RadioItem(
label: String,
selected: Boolean,
onClick: () -> Unit,
) {
Row(
modifier = Modifier
.clickable(onClick = onClick)
.fillMaxWidth()
.padding(horizontal = TabbedDialogPaddings.Horizontal, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
RadioButton(
selected = selected,
onClick = null,
)
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
)
}
}

View File

@ -32,6 +32,11 @@ import androidx.compose.ui.util.fastForEachIndexed
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
object TabbedDialogPaddings {
val Horizontal = 24.dp
val Vertical = 8.dp
}
@Composable @Composable
fun TabbedDialog( fun TabbedDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
@ -72,9 +77,7 @@ fun TabbedDialog(
} }
} }
tabOverflowMenuContent?.let { tabOverflowMenuContent?.let { MoreMenu(it) }
MoreMenu(tabOverflowMenuContent)
}
} }
Divider() Divider()

View File

@ -3,27 +3,19 @@ package eu.kanade.presentation.manga
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDownward
import androidx.compose.material.icons.filled.ArrowUpward
import androidx.compose.material.icons.outlined.PeopleAlt import androidx.compose.material.icons.outlined.PeopleAlt
import androidx.compose.material.icons.rounded.CheckBox
import androidx.compose.material.icons.rounded.CheckBoxOutlineBlank
import androidx.compose.material.icons.rounded.DisabledByDefault
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Checkbox import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -33,12 +25,15 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue 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.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.TriStateFilter import eu.kanade.domain.manga.model.TriStateFilter
import eu.kanade.presentation.components.RadioItem
import eu.kanade.presentation.components.SortItem
import eu.kanade.presentation.components.TabbedDialog import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.presentation.components.TriStateItem
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@Composable @Composable
@ -78,11 +73,16 @@ fun ChapterSettingsDialog(
) )
}, },
) { contentPadding, page -> ) { contentPadding, page ->
Column(
modifier = Modifier
.padding(contentPadding)
.padding(vertical = TabbedDialogPaddings.Vertical)
.verticalScroll(rememberScrollState()),
) {
when (page) { when (page) {
0 -> { 0 -> {
val forceDownloaded = manga?.forceDownloaded() == true val forceDownloaded = manga?.forceDownloaded() == true
FilterPage( FilterPage(
contentPadding = contentPadding,
downloadFilter = if (forceDownloaded) { downloadFilter = if (forceDownloaded) {
TriStateFilter.ENABLED_NOT TriStateFilter.ENABLED_NOT
} else { } else {
@ -100,7 +100,6 @@ fun ChapterSettingsDialog(
} }
1 -> { 1 -> {
SortPage( SortPage(
contentPadding = contentPadding,
sortingMode = manga?.sorting ?: 0, sortingMode = manga?.sorting ?: 0,
sortDescending = manga?.sortDescending() ?: false, sortDescending = manga?.sortDescending() ?: false,
onItemSelected = onSortModeChanged, onItemSelected = onSortModeChanged,
@ -108,13 +107,13 @@ fun ChapterSettingsDialog(
} }
2 -> { 2 -> {
DisplayPage( DisplayPage(
contentPadding = contentPadding,
displayMode = manga?.displayMode ?: 0, displayMode = manga?.displayMode ?: 0,
onItemSelected = onDisplayModeChanged, onItemSelected = onDisplayModeChanged,
) )
} }
} }
} }
}
} }
@Composable @Composable
@ -157,6 +156,7 @@ private fun SetAsDefaultDialog(
TextButton( TextButton(
onClick = { onClick = {
onConfirmed(optionalChecked) onConfirmed(optionalChecked)
onDismissRequest()
}, },
) { ) {
Text(text = stringResource(android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
@ -166,8 +166,7 @@ private fun SetAsDefaultDialog(
} }
@Composable @Composable
private fun FilterPage( private fun ColumnScope.FilterPage(
contentPadding: PaddingValues,
downloadFilter: TriStateFilter, downloadFilter: TriStateFilter,
onDownloadFilterChanged: ((TriStateFilter) -> Unit)?, onDownloadFilterChanged: ((TriStateFilter) -> Unit)?,
unreadFilter: TriStateFilter, unreadFilter: TriStateFilter,
@ -178,23 +177,17 @@ private fun FilterPage(
onClickShowScanlatorSelection: (() -> Unit)?, onClickShowScanlatorSelection: (() -> Unit)?,
// SY <-- // SY <--
) { ) {
Column( TriStateItem(
modifier = Modifier
.padding(vertical = VerticalPadding)
.padding(contentPadding)
.verticalScroll(rememberScrollState()),
) {
FilterPageItem(
label = stringResource(R.string.label_downloaded), label = stringResource(R.string.label_downloaded),
state = downloadFilter, state = downloadFilter,
onClick = onDownloadFilterChanged, onClick = onDownloadFilterChanged,
) )
FilterPageItem( TriStateItem(
label = stringResource(R.string.action_filter_unread), label = stringResource(R.string.action_filter_unread),
state = unreadFilter, state = unreadFilter,
onClick = onUnreadFilterChanged, onClick = onUnreadFilterChanged,
) )
FilterPageItem( TriStateItem(
label = stringResource(R.string.action_filter_bookmarked), label = stringResource(R.string.action_filter_bookmarked),
state = bookmarkedFilter, state = bookmarkedFilter,
onClick = onBookmarkedFilterChanged, onClick = onBookmarkedFilterChanged,
@ -204,50 +197,6 @@ private fun FilterPage(
SetScanlatorsItem(onClickShowScanlatorSelection) SetScanlatorsItem(onClickShowScanlatorSelection)
} }
// SY <-- // SY <--
}
}
@Composable
private fun FilterPageItem(
label: String,
state: TriStateFilter,
onClick: ((TriStateFilter) -> Unit)?,
) {
Row(
modifier = Modifier
.clickable(
enabled = onClick != null,
onClick = {
when (state) {
TriStateFilter.DISABLED -> onClick?.invoke(TriStateFilter.ENABLED_IS)
TriStateFilter.ENABLED_IS -> onClick?.invoke(TriStateFilter.ENABLED_NOT)
TriStateFilter.ENABLED_NOT -> onClick?.invoke(TriStateFilter.DISABLED)
}
},
)
.fillMaxWidth()
.padding(horizontal = HorizontalPadding, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
Icon(
imageVector = when (state) {
TriStateFilter.DISABLED -> Icons.Rounded.CheckBoxOutlineBlank
TriStateFilter.ENABLED_IS -> Icons.Rounded.CheckBox
TriStateFilter.ENABLED_NOT -> Icons.Rounded.DisabledByDefault
},
contentDescription = null,
tint = if (state == TriStateFilter.DISABLED) {
MaterialTheme.colorScheme.onSurfaceVariant
} else {
MaterialTheme.colorScheme.primary
},
)
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
)
}
} }
// SY --> // SY -->
@ -261,7 +210,7 @@ private fun SetScanlatorsItem(
onClick = onClickShowScanlatorSelection, onClick = onClickShowScanlatorSelection,
) )
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = HorizontalPadding, vertical = 12.dp), .padding(horizontal = TabbedDialogPaddings.Horizontal, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp), horizontalArrangement = Arrangement.spacedBy(24.dp),
) { ) {
@ -278,121 +227,41 @@ private fun SetScanlatorsItem(
// SY <-- // SY <--
@Composable @Composable
private fun SortPage( private fun ColumnScope.SortPage(
contentPadding: PaddingValues,
sortingMode: Long, sortingMode: Long,
sortDescending: Boolean, sortDescending: Boolean,
onItemSelected: (Long) -> Unit, onItemSelected: (Long) -> Unit,
) { ) {
Column( SortItem(
modifier = Modifier
.padding(contentPadding)
.padding(vertical = VerticalPadding)
.verticalScroll(rememberScrollState()),
) {
val arrowIcon = if (sortDescending) {
Icons.Default.ArrowDownward
} else {
Icons.Default.ArrowUpward
}
SortPageItem(
label = stringResource(R.string.sort_by_source), label = stringResource(R.string.sort_by_source),
statusIcon = arrowIcon.takeIf { sortingMode == Manga.CHAPTER_SORTING_SOURCE }, sortDescending = sortDescending.takeIf { sortingMode == Manga.CHAPTER_SORTING_SOURCE },
onClick = { onItemSelected(Manga.CHAPTER_SORTING_SOURCE) }, onClick = { onItemSelected(Manga.CHAPTER_SORTING_SOURCE) },
) )
SortPageItem( SortItem(
label = stringResource(R.string.sort_by_number), label = stringResource(R.string.sort_by_number),
statusIcon = arrowIcon.takeIf { sortingMode == Manga.CHAPTER_SORTING_NUMBER }, sortDescending = sortDescending.takeIf { sortingMode == Manga.CHAPTER_SORTING_NUMBER },
onClick = { onItemSelected(Manga.CHAPTER_SORTING_NUMBER) }, onClick = { onItemSelected(Manga.CHAPTER_SORTING_NUMBER) },
) )
SortPageItem( SortItem(
label = stringResource(R.string.sort_by_upload_date), label = stringResource(R.string.sort_by_upload_date),
statusIcon = arrowIcon.takeIf { sortingMode == Manga.CHAPTER_SORTING_UPLOAD_DATE }, sortDescending = sortDescending.takeIf { sortingMode == Manga.CHAPTER_SORTING_UPLOAD_DATE },
onClick = { onItemSelected(Manga.CHAPTER_SORTING_UPLOAD_DATE) }, onClick = { onItemSelected(Manga.CHAPTER_SORTING_UPLOAD_DATE) },
) )
}
} }
@Composable @Composable
private fun SortPageItem( private fun ColumnScope.DisplayPage(
label: String,
statusIcon: ImageVector?,
onClick: () -> Unit,
) {
Row(
modifier = Modifier
.clickable(onClick = onClick)
.fillMaxWidth()
.padding(horizontal = HorizontalPadding, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
if (statusIcon != null) {
Icon(
imageVector = statusIcon,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
)
} else {
Spacer(modifier = Modifier.size(24.dp))
}
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
)
}
}
@Composable
private fun DisplayPage(
contentPadding: PaddingValues,
displayMode: Long, displayMode: Long,
onItemSelected: (Long) -> Unit, onItemSelected: (Long) -> Unit,
) { ) {
Column( RadioItem(
modifier = Modifier
.padding(contentPadding)
.padding(vertical = VerticalPadding)
.verticalScroll(rememberScrollState()),
) {
DisplayPageItem(
label = stringResource(R.string.show_title), label = stringResource(R.string.show_title),
selected = displayMode == Manga.CHAPTER_DISPLAY_NAME, selected = displayMode == Manga.CHAPTER_DISPLAY_NAME,
onClick = { onItemSelected(Manga.CHAPTER_DISPLAY_NAME) }, onClick = { onItemSelected(Manga.CHAPTER_DISPLAY_NAME) },
) )
DisplayPageItem( RadioItem(
label = stringResource(R.string.show_chapter_number), label = stringResource(R.string.show_chapter_number),
selected = displayMode == Manga.CHAPTER_DISPLAY_NUMBER, selected = displayMode == Manga.CHAPTER_DISPLAY_NUMBER,
onClick = { onItemSelected(Manga.CHAPTER_DISPLAY_NUMBER) }, onClick = { onItemSelected(Manga.CHAPTER_DISPLAY_NUMBER) },
) )
}
} }
@Composable
private fun DisplayPageItem(
label: String,
selected: Boolean,
onClick: () -> Unit,
) {
Row(
modifier = Modifier
.clickable(onClick = onClick)
.fillMaxWidth()
.padding(horizontal = HorizontalPadding, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
RadioButton(
selected = selected,
onClick = null,
)
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
)
}
}
private val HorizontalPadding = 24.dp
private val VerticalPadding = 8.dp