Move library columns settings to library sheet

Closes #3969. Dialog-ception.
This commit is contained in:
arkon 2023-04-15 19:36:49 -04:00
parent 8a18e10cc2
commit c6ac992798
4 changed files with 166 additions and 150 deletions

View File

@ -0,0 +1,126 @@
package eu.kanade.presentation.library
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
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.text.style.TextAlign
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import tachiyomi.presentation.core.components.WheelPickerDefaults
import tachiyomi.presentation.core.components.WheelTextPicker
@Composable
fun LibraryColumnsDialog(
initialPortrait: Int,
initialLandscape: Int,
onDismissRequest: () -> Unit,
onValueChanged: (portrait: Int, landscape: Int) -> Unit,
) {
var portraitValue by rememberSaveable { mutableStateOf(initialPortrait) }
var landscapeValue by rememberSaveable { mutableStateOf(initialLandscape) }
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_library_columns)) },
text = {
Column {
Row {
Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.portrait),
textAlign = TextAlign.Center,
maxLines = 1,
style = MaterialTheme.typography.labelMedium,
)
Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.landscape),
textAlign = TextAlign.Center,
maxLines = 1,
style = MaterialTheme.typography.labelMedium,
)
}
LibraryColumnsPicker(
modifier = Modifier.fillMaxWidth(),
portraitValue = portraitValue,
onPortraitChange = { portraitValue = it },
landscapeValue = landscapeValue,
onLandscapeChange = { landscapeValue = it },
)
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
}
},
confirmButton = {
TextButton(
enabled = portraitValue != initialPortrait || landscapeValue != initialLandscape,
onClick = { onValueChanged(portraitValue, landscapeValue) },
) {
Text(text = stringResource(android.R.string.ok))
}
},
)
}
@Composable
private fun LibraryColumnsPicker(
modifier: Modifier = Modifier,
portraitValue: Int,
onPortraitChange: (Int) -> Unit,
landscapeValue: Int,
onLandscapeChange: (Int) -> Unit,
) {
BoxWithConstraints(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
WheelPickerDefaults.Background(size = DpSize(maxWidth, 128.dp))
val size = DpSize(width = maxWidth / 2, height = 128.dp)
Row {
val columns = (0..10).map { getColumnValue(value = it) }
WheelTextPicker(
startIndex = portraitValue,
items = columns,
size = size,
onSelectionChanged = onPortraitChange,
backgroundContent = null,
)
WheelTextPicker(
startIndex = landscapeValue,
items = columns,
size = size,
onSelectionChanged = onLandscapeChange,
backgroundContent = null,
)
}
}
}
@Composable
@ReadOnlyComposable
private fun getColumnValue(value: Int): String {
return if (value == 0) {
stringResource(R.string.label_default)
} else {
value.toString()
}
}

View File

@ -7,6 +7,9 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.TabbedDialog
@ -22,6 +25,7 @@ import tachiyomi.domain.library.model.display
import tachiyomi.domain.library.model.sort
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.model.TriStateFilter
import tachiyomi.presentation.core.components.BasicItem
import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.RadioItem
@ -170,6 +174,23 @@ private fun ColumnScope.DisplayPage(
category: Category,
screenModel: LibrarySettingsScreenModel,
) {
val portraitColumns by screenModel.libraryPreferences.portraitColumns().collectAsState()
val landscapeColumns by screenModel.libraryPreferences.landscapeColumns().collectAsState()
var showColumnsDialog by rememberSaveable { mutableStateOf(false) }
if (showColumnsDialog) {
LibraryColumnsDialog(
initialPortrait = portraitColumns,
initialLandscape = landscapeColumns,
onDismissRequest = { showColumnsDialog = false },
onValueChanged = { portrait, landscape ->
screenModel.libraryPreferences.portraitColumns().set(portrait)
screenModel.libraryPreferences.landscapeColumns().set(landscape)
showColumnsDialog = false
},
)
}
HeadingItem(R.string.action_display_mode)
listOf(
R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
@ -184,6 +205,13 @@ private fun ColumnScope.DisplayPage(
)
}
if (category.display != LibraryDisplayMode.List) {
BasicItem(
label = stringResource(R.string.pref_library_columns),
onClick = { showColumnsDialog = true },
)
}
HeadingItem(R.string.overlay_header)
val downloadBadge by screenModel.libraryPreferences.downloadBadge().collectAsState()
CheckboxItem(

View File

@ -1,14 +1,6 @@
package eu.kanade.presentation.more.settings.screen
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.collectAsState
@ -18,14 +10,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastMap
import androidx.core.content.ContextCompat
import cafe.adriel.voyager.navigator.LocalNavigator
@ -52,8 +39,6 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_ONLY
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_HAS_UNREAD
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_COMPLETED
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_READ
import tachiyomi.presentation.core.components.WheelPickerDefaults
import tachiyomi.presentation.core.components.WheelTextPicker
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -71,45 +56,11 @@ object SettingsLibraryScreen : SearchableSettings {
val allCategories by getCategories.subscribe().collectAsState(initial = runBlocking { getCategories.await() })
return mutableListOf(
getDisplayGroup(libraryPreferences),
getCategoriesGroup(LocalNavigator.currentOrThrow, allCategories, libraryPreferences),
getGlobalUpdateGroup(allCategories, libraryPreferences),
)
}
@Composable
private fun getDisplayGroup(libraryPreferences: LibraryPreferences): Preference.PreferenceGroup {
val scope = rememberCoroutineScope()
val portraitColumns by libraryPreferences.portraitColumns().stateIn(scope).collectAsState()
val landscapeColumns by libraryPreferences.landscapeColumns().stateIn(scope).collectAsState()
var showDialog by rememberSaveable { mutableStateOf(false) }
if (showDialog) {
LibraryColumnsDialog(
initialPortrait = portraitColumns,
initialLandscape = landscapeColumns,
onDismissRequest = { showDialog = false },
onValueChanged = { portrait, landscape ->
libraryPreferences.portraitColumns().set(portrait)
libraryPreferences.landscapeColumns().set(landscape)
showDialog = false
},
)
}
return Preference.PreferenceGroup(
title = stringResource(R.string.pref_category_display),
preferenceItems = listOf(
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_library_columns),
subtitle = "${stringResource(R.string.portrait)}: ${getColumnValue(portraitColumns)}, " +
"${stringResource(R.string.landscape)}: ${getColumnValue(landscapeColumns)}",
onClick = { showDialog = true },
),
),
)
}
@Composable
private fun getCategoriesGroup(
navigator: Navigator,
@ -265,105 +216,4 @@ object SettingsLibraryScreen : SearchableSettings {
),
)
}
@Composable
private fun LibraryColumnsDialog(
initialPortrait: Int,
initialLandscape: Int,
onDismissRequest: () -> Unit,
onValueChanged: (portrait: Int, landscape: Int) -> Unit,
) {
var portraitValue by rememberSaveable { mutableStateOf(initialPortrait) }
var landscapeValue by rememberSaveable { mutableStateOf(initialLandscape) }
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_library_columns)) },
text = {
Column {
Row {
Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.portrait),
textAlign = TextAlign.Center,
maxLines = 1,
style = MaterialTheme.typography.labelMedium,
)
Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.landscape),
textAlign = TextAlign.Center,
maxLines = 1,
style = MaterialTheme.typography.labelMedium,
)
}
LibraryColumnsPicker(
modifier = Modifier.fillMaxWidth(),
portraitValue = portraitValue,
onPortraitChange = { portraitValue = it },
landscapeValue = landscapeValue,
onLandscapeChange = { landscapeValue = it },
)
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
}
},
confirmButton = {
TextButton(
enabled = portraitValue != initialPortrait || landscapeValue != initialLandscape,
onClick = { onValueChanged(portraitValue, landscapeValue) },
) {
Text(text = stringResource(android.R.string.ok))
}
},
)
}
@Composable
private fun LibraryColumnsPicker(
modifier: Modifier = Modifier,
portraitValue: Int,
onPortraitChange: (Int) -> Unit,
landscapeValue: Int,
onLandscapeChange: (Int) -> Unit,
) {
BoxWithConstraints(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
WheelPickerDefaults.Background(size = DpSize(maxWidth, 128.dp))
val size = DpSize(width = maxWidth / 2, height = 128.dp)
Row {
val columns = (0..10).map { getColumnValue(value = it) }
WheelTextPicker(
startIndex = portraitValue,
items = columns,
size = size,
onSelectionChanged = onPortraitChange,
backgroundContent = null,
)
WheelTextPicker(
startIndex = landscapeValue,
items = columns,
size = size,
onSelectionChanged = onLandscapeChange,
backgroundContent = null,
)
}
}
}
@Composable
@ReadOnlyComposable
private fun getColumnValue(value: Int): String {
return if (value == 0) {
stringResource(R.string.label_default)
} else {
value.toString()
}
}
}

View File

@ -49,6 +49,18 @@ fun HeadingItem(
)
}
@Composable
fun BasicItem(
label: String,
onClick: () -> Unit,
) {
SortItem(
label = label,
sortDescending = null,
onClick = onClick,
)
}
@Composable
fun SortItem(
label: String,