123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- package eu.kanade.presentation.manga
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.Box
- import androidx.compose.foundation.layout.BoxScope
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.RowScope
- import androidx.compose.foundation.layout.Spacer
- import androidx.compose.foundation.layout.WindowInsets
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.padding
- import androidx.compose.foundation.layout.systemBars
- import androidx.compose.foundation.layout.windowInsetsPadding
- import androidx.compose.foundation.lazy.rememberLazyListState
- import androidx.compose.foundation.selection.selectable
- import androidx.compose.foundation.shape.RoundedCornerShape
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.RadioButton
- 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.Modifier
- import androidx.compose.ui.draw.clip
- import androidx.compose.ui.res.stringResource
- import androidx.compose.ui.text.style.TextAlign
- import androidx.compose.ui.unit.dp
- import eu.kanade.presentation.components.ScrollbarLazyColumn
- import eu.kanade.presentation.components.WheelDatePicker
- import eu.kanade.presentation.components.WheelTextPicker
- import eu.kanade.presentation.util.isScrolledToEnd
- import eu.kanade.presentation.util.isScrolledToStart
- import eu.kanade.presentation.util.minimumTouchTargetSize
- import eu.kanade.presentation.util.padding
- import eu.kanade.tachiyomi.R
- import tachiyomi.presentation.core.components.material.AlertDialogContent
- import tachiyomi.presentation.core.components.material.Divider
- import java.time.LocalDate
- import java.time.format.TextStyle
- @Composable
- fun TrackStatusSelector(
- selection: Int,
- onSelectionChange: (Int) -> Unit,
- selections: Map<Int, String>,
- onConfirm: () -> Unit,
- onDismissRequest: () -> Unit,
- ) {
- BaseSelector(
- title = stringResource(R.string.status),
- content = {
- val state = rememberLazyListState()
- ScrollbarLazyColumn(state = state) {
- selections.forEach { (key, value) ->
- val isSelected = selection == key
- item {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .clip(RoundedCornerShape(8.dp))
- .selectable(
- selected = isSelected,
- onClick = { onSelectionChange(key) },
- )
- .fillMaxWidth()
- .minimumTouchTargetSize(),
- ) {
- RadioButton(
- selected = isSelected,
- onClick = null,
- )
- Text(
- text = value,
- style = MaterialTheme.typography.bodyLarge.merge(),
- modifier = Modifier.padding(start = 24.dp),
- )
- }
- }
- }
- }
- if (!state.isScrolledToStart()) Divider(modifier = Modifier.align(Alignment.TopCenter))
- if (!state.isScrolledToEnd()) Divider(modifier = Modifier.align(Alignment.BottomCenter))
- },
- onConfirm = onConfirm,
- onDismissRequest = onDismissRequest,
- )
- }
- @Composable
- fun TrackChapterSelector(
- selection: Int,
- onSelectionChange: (Int) -> Unit,
- range: Iterable<Int>,
- onConfirm: () -> Unit,
- onDismissRequest: () -> Unit,
- ) {
- BaseSelector(
- title = stringResource(R.string.chapters),
- content = {
- WheelTextPicker(
- modifier = Modifier.align(Alignment.Center),
- startIndex = selection,
- texts = range.map { "$it" },
- onSelectionChanged = { onSelectionChange(it) },
- )
- },
- onConfirm = onConfirm,
- onDismissRequest = onDismissRequest,
- )
- }
- @Composable
- fun TrackScoreSelector(
- selection: String,
- onSelectionChange: (String) -> Unit,
- selections: List<String>,
- onConfirm: () -> Unit,
- onDismissRequest: () -> Unit,
- ) {
- BaseSelector(
- title = stringResource(R.string.score),
- content = {
- WheelTextPicker(
- modifier = Modifier.align(Alignment.Center),
- startIndex = selections.indexOf(selection).coerceAtLeast(0),
- texts = selections,
- onSelectionChanged = { onSelectionChange(selections[it]) },
- )
- },
- onConfirm = onConfirm,
- onDismissRequest = onDismissRequest,
- )
- }
- @Composable
- fun TrackDateSelector(
- title: String,
- minDate: LocalDate?,
- maxDate: LocalDate?,
- selection: LocalDate,
- onSelectionChange: (LocalDate) -> Unit,
- onConfirm: () -> Unit,
- onRemove: (() -> Unit)?,
- onDismissRequest: () -> Unit,
- ) {
- BaseSelector(
- title = title,
- content = {
- Row(
- modifier = Modifier.align(Alignment.Center),
- verticalAlignment = Alignment.CenterVertically,
- ) {
- var internalSelection by remember { mutableStateOf(selection) }
- Text(
- modifier = Modifier
- .weight(1f)
- .padding(end = 16.dp),
- text = internalSelection.dayOfWeek
- .getDisplayName(TextStyle.SHORT, java.util.Locale.getDefault()),
- textAlign = TextAlign.Center,
- style = MaterialTheme.typography.titleMedium,
- )
- WheelDatePicker(
- startDate = selection,
- minDate = minDate,
- maxDate = maxDate,
- onSelectionChanged = {
- internalSelection = it
- onSelectionChange(it)
- },
- )
- }
- },
- thirdButton = if (onRemove != null) {
- {
- TextButton(onClick = onRemove) {
- Text(text = stringResource(R.string.action_remove))
- }
- }
- } else {
- null
- },
- onConfirm = onConfirm,
- onDismissRequest = onDismissRequest,
- )
- }
- @Composable
- private fun BaseSelector(
- title: String,
- content: @Composable BoxScope.() -> Unit,
- thirdButton: @Composable (RowScope.() -> Unit)? = null,
- onConfirm: () -> Unit,
- onDismissRequest: () -> Unit,
- ) {
- AlertDialogContent(
- modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars),
- title = { Text(text = title) },
- text = {
- Box(
- modifier = Modifier.fillMaxWidth(),
- content = content,
- )
- },
- buttons = {
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small, Alignment.End),
- ) {
- if (thirdButton != null) {
- thirdButton()
- Spacer(modifier = Modifier.weight(1f))
- }
- TextButton(onClick = onDismissRequest) {
- Text(text = stringResource(android.R.string.cancel))
- }
- TextButton(onClick = onConfirm) {
- Text(text = stringResource(android.R.string.ok))
- }
- }
- },
- )
- }
|