123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- package eu.kanade.presentation.library
- import android.content.res.Configuration
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.ColumnScope
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.padding
- import androidx.compose.foundation.rememberScrollState
- import androidx.compose.foundation.verticalScroll
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.Slider
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.runtime.collectAsState
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.remember
- import androidx.compose.runtime.setValue
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.platform.LocalConfiguration
- import androidx.compose.ui.res.stringResource
- import androidx.compose.ui.unit.dp
- import eu.kanade.presentation.components.TabbedDialog
- import eu.kanade.presentation.components.TabbedDialogPaddings
- import eu.kanade.presentation.components.TriStateItem
- import eu.kanade.presentation.util.collectAsState
- import eu.kanade.tachiyomi.R
- import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel
- import kotlinx.coroutines.flow.map
- import tachiyomi.domain.category.model.Category
- import tachiyomi.domain.library.model.LibraryDisplayMode
- import tachiyomi.domain.library.model.LibrarySort
- 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.CheckboxItem
- import tachiyomi.presentation.core.components.HeadingItem
- import tachiyomi.presentation.core.components.RadioItem
- import tachiyomi.presentation.core.components.SettingsItemsPaddings
- import tachiyomi.presentation.core.components.SortItem
- @Composable
- fun LibrarySettingsDialog(
- onDismissRequest: () -> Unit,
- screenModel: LibrarySettingsScreenModel,
- category: Category,
- ) {
- TabbedDialog(
- onDismissRequest = onDismissRequest,
- tabTitles = listOf(
- stringResource(R.string.action_filter),
- stringResource(R.string.action_sort),
- stringResource(R.string.action_display),
- ),
- ) { page ->
- Column(
- modifier = Modifier
- .padding(vertical = TabbedDialogPaddings.Vertical)
- .verticalScroll(rememberScrollState()),
- ) {
- when (page) {
- 0 -> FilterPage(
- screenModel = screenModel,
- )
- 1 -> SortPage(
- category = category,
- screenModel = screenModel,
- )
- 2 -> DisplayPage(
- category = category,
- screenModel = screenModel,
- )
- }
- }
- }
- }
- @Composable
- private fun ColumnScope.FilterPage(
- screenModel: LibrarySettingsScreenModel,
- ) {
- val filterDownloaded by screenModel.libraryPreferences.filterDownloaded().collectAsState()
- val downloadedOnly by screenModel.preferences.downloadedOnly().collectAsState()
- TriStateItem(
- label = stringResource(R.string.label_downloaded),
- state = if (downloadedOnly) {
- TriStateFilter.ENABLED_IS
- } else {
- filterDownloaded
- },
- enabled = !downloadedOnly,
- onClick = { screenModel.toggleFilter(LibraryPreferences::filterDownloaded) },
- )
- val filterUnread by screenModel.libraryPreferences.filterUnread().collectAsState()
- TriStateItem(
- label = stringResource(R.string.action_filter_unread),
- state = filterUnread,
- onClick = { screenModel.toggleFilter(LibraryPreferences::filterUnread) },
- )
- val filterStarted by screenModel.libraryPreferences.filterStarted().collectAsState()
- TriStateItem(
- label = stringResource(R.string.label_started),
- state = filterStarted,
- onClick = { screenModel.toggleFilter(LibraryPreferences::filterStarted) },
- )
- val filterBookmarked by screenModel.libraryPreferences.filterBookmarked().collectAsState()
- TriStateItem(
- label = stringResource(R.string.action_filter_bookmarked),
- state = filterBookmarked,
- onClick = { screenModel.toggleFilter(LibraryPreferences::filterBookmarked) },
- )
- val filterCompleted by screenModel.libraryPreferences.filterCompleted().collectAsState()
- TriStateItem(
- label = stringResource(R.string.completed),
- state = filterCompleted,
- onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompleted) },
- )
- val trackServices = remember { screenModel.trackServices }
- when (trackServices.size) {
- 0 -> {
- // No trackers
- }
- 1 -> {
- val service = trackServices[0]
- val filterTracker by screenModel.libraryPreferences.filterTracking(service.id.toInt()).collectAsState()
- TriStateItem(
- label = stringResource(R.string.action_filter_tracked),
- state = filterTracker,
- onClick = { screenModel.toggleTracker(service.id.toInt()) },
- )
- }
- else -> {
- HeadingItem(R.string.action_filter_tracked)
- trackServices.map { service ->
- val filterTracker by screenModel.libraryPreferences.filterTracking(service.id.toInt()).collectAsState()
- TriStateItem(
- label = stringResource(service.nameRes()),
- state = filterTracker,
- onClick = { screenModel.toggleTracker(service.id.toInt()) },
- )
- }
- }
- }
- }
- @Composable
- private fun ColumnScope.SortPage(
- category: Category,
- screenModel: LibrarySettingsScreenModel,
- ) {
- val sortingMode = category.sort.type
- val sortDescending = !category.sort.isAscending
- listOf(
- R.string.action_sort_alpha to LibrarySort.Type.Alphabetical,
- R.string.action_sort_total to LibrarySort.Type.TotalChapters,
- R.string.action_sort_last_read to LibrarySort.Type.LastRead,
- R.string.action_sort_last_manga_update to LibrarySort.Type.LastUpdate,
- R.string.action_sort_unread_count to LibrarySort.Type.UnreadCount,
- R.string.action_sort_latest_chapter to LibrarySort.Type.LatestChapter,
- R.string.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate,
- R.string.action_sort_date_added to LibrarySort.Type.DateAdded,
- ).map { (titleRes, mode) ->
- SortItem(
- label = stringResource(titleRes),
- sortDescending = sortDescending.takeIf { sortingMode == mode },
- onClick = {
- val isTogglingDirection = sortingMode == mode
- val direction = when {
- isTogglingDirection -> if (sortDescending) LibrarySort.Direction.Ascending else LibrarySort.Direction.Descending
- else -> if (sortDescending) LibrarySort.Direction.Descending else LibrarySort.Direction.Ascending
- }
- screenModel.setSort(category, mode, direction)
- },
- )
- }
- }
- @Composable
- private fun ColumnScope.DisplayPage(
- category: Category,
- screenModel: LibrarySettingsScreenModel,
- ) {
- HeadingItem(R.string.action_display_mode)
- listOf(
- R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
- R.string.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid,
- R.string.action_display_cover_only_grid to LibraryDisplayMode.CoverOnlyGrid,
- R.string.action_display_list to LibraryDisplayMode.List,
- ).map { (titleRes, mode) ->
- RadioItem(
- label = stringResource(titleRes),
- selected = category.display == mode,
- onClick = { screenModel.setDisplayMode(category, mode) },
- )
- }
- if (category.display != LibraryDisplayMode.List) {
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- horizontal = SettingsItemsPaddings.Horizontal,
- vertical = SettingsItemsPaddings.Vertical,
- ),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(24.dp),
- ) {
- val configuration = LocalConfiguration.current
- val columnPreference = remember {
- if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- screenModel.libraryPreferences.landscapeColumns()
- } else {
- screenModel.libraryPreferences.portraitColumns()
- }
- }
- val columns by columnPreference.changes().collectAsState(initial = 0)
- Column(
- Modifier.weight(.5f),
- ) {
- Text(
- stringResource(id = R.string.pref_library_columns),
- style = MaterialTheme.typography.bodyMedium,
- )
- if (columns > 0) {
- Text(stringResource(id = R.string.pref_library_columns_per_row, columns))
- } else {
- Text(stringResource(id = R.string.label_default))
- }
- }
- Slider(
- value = columns.toFloat(),
- onValueChange = { columnPreference.set(it.toInt()) },
- modifier = Modifier.weight(1.5f),
- valueRange = 0f..10f,
- steps = 10,
- )
- }
- }
- HeadingItem(R.string.overlay_header)
- val downloadBadge by screenModel.libraryPreferences.downloadBadge().collectAsState()
- CheckboxItem(
- label = stringResource(R.string.action_display_download_badge),
- checked = downloadBadge,
- onClick = {
- screenModel.togglePreference(LibraryPreferences::downloadBadge)
- },
- )
- val localBadge by screenModel.libraryPreferences.localBadge().collectAsState()
- CheckboxItem(
- label = stringResource(R.string.action_display_local_badge),
- checked = localBadge,
- onClick = {
- screenModel.togglePreference(LibraryPreferences::localBadge)
- },
- )
- val languageBadge by screenModel.libraryPreferences.languageBadge().collectAsState()
- CheckboxItem(
- label = stringResource(R.string.action_display_language_badge),
- checked = languageBadge,
- onClick = {
- screenModel.togglePreference(LibraryPreferences::languageBadge)
- },
- )
- val showContinueReadingButton by screenModel.libraryPreferences.showContinueReadingButton().collectAsState()
- CheckboxItem(
- label = stringResource(R.string.action_display_show_continue_reading_button),
- checked = showContinueReadingButton,
- onClick = {
- screenModel.togglePreference(LibraryPreferences::showContinueReadingButton)
- },
- )
- HeadingItem(R.string.tabs_header)
- val categoryTabs by screenModel.libraryPreferences.categoryTabs().collectAsState()
- CheckboxItem(
- label = stringResource(R.string.action_display_show_tabs),
- checked = categoryTabs,
- onClick = {
- screenModel.togglePreference(LibraryPreferences::categoryTabs)
- },
- )
- val categoryNumberOfItems by screenModel.libraryPreferences.categoryNumberOfItems().collectAsState()
- CheckboxItem(
- label = stringResource(R.string.action_display_show_number_of_items),
- checked = categoryNumberOfItems,
- onClick = {
- screenModel.togglePreference(LibraryPreferences::categoryNumberOfItems)
- },
- )
- }
|