komikku/app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt
arkon 6fbf250796 Move more things to domain/data modules
(cherry picked from commit bebd4be43d73617de2cfbc1ff4289e81f535a8e6)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsGeneralScreen.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
#	data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt
#	data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt
#	domain/build.gradle.kts
#	domain/src/main/java/tachiyomi/domain/category/interactor/SetDisplayModeForCategory.kt
#	domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt
#	domain/src/main/java/tachiyomi/domain/history/interactor/GetHistoryByMangaId.kt
#	domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt
2023-03-15 00:23:28 -04:00

349 lines
13 KiB
Kotlin

package eu.kanade.presentation.library
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastForEach
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.LibraryGroup
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.IconItem
import tachiyomi.presentation.core.components.RadioItem
import tachiyomi.presentation.core.components.SortItem
@Composable
fun LibrarySettingsDialog(
onDismissRequest: () -> Unit,
screenModel: LibrarySettingsScreenModel,
category: Category,
// SY -->
hasCategories: Boolean,
// SY <--
) {
TabbedDialog(
onDismissRequest = onDismissRequest,
tabTitles = listOf(
stringResource(R.string.action_filter),
stringResource(R.string.action_sort),
stringResource(R.string.action_display),
// SY -->
stringResource(R.string.group),
// SY <--
),
) { contentPadding, page ->
Column(
modifier = Modifier
.padding(contentPadding)
.padding(vertical = TabbedDialogPaddings.Vertical)
.verticalScroll(rememberScrollState()),
) {
when (page) {
0 -> FilterPage(
screenModel = screenModel,
)
1 -> SortPage(
category = category,
screenModel = screenModel,
)
2 -> DisplayPage(
category = category,
screenModel = screenModel,
)
// SY -->
3 -> GroupPage(
screenModel = screenModel,
hasCategories = hasCategories,
)
// SY <--
}
}
}
}
@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) },
)
// SY -->
val filterLewd by screenModel.libraryPreferences.filterLewd().collectAsState()
TriStateItem(
label = stringResource(R.string.lewd),
state = filterLewd,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterLewd) },
)
// SY <--
when (screenModel.trackServices.size) {
0 -> {
// No trackers
}
1 -> {
val service = screenModel.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)
screenModel.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,
) {
// SY -->
val globalSortMode by screenModel.libraryPreferences.librarySortingMode().collectAsState()
val sortingMode = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
category.sort.type
} else {
globalSortMode.type
}
val sortDescending = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
category.sort.isAscending
} else {
globalSortMode.isAscending
}.not()
val hasSortTags by remember {
screenModel.libraryPreferences.sortTagsForLibrary().changes()
.map { it.isNotEmpty() }
}.collectAsState(initial = screenModel.libraryPreferences.sortTagsForLibrary().get().isNotEmpty())
// SY <--
listOfNotNull(
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,
if (hasSortTags) {
R.string.tag_sorting to LibrarySort.Type.TagList
} else {
null
},
).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,
) {
// SY -->
val globalDisplayMode by screenModel.libraryPreferences.libraryDisplayMode().collectAsState()
// SY <--
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),
// SY -->
selected = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
category.display
} else {
globalDisplayMode
} == mode,
// SY <--
onClick = { screenModel.setDisplayMode(category, mode) },
)
}
HeadingItem(R.string.badges_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)
},
)
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)
},
)
HeadingItem(R.string.other_header)
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)
},
)
}
data class GroupMode(
val int: Int,
val nameRes: Int,
val drawableRes: Int,
)
private fun groupTypeDrawableRes(type: Int): Int {
return when (type) {
LibraryGroup.BY_STATUS -> R.drawable.ic_progress_clock_24dp
LibraryGroup.BY_TRACK_STATUS -> R.drawable.ic_sync_24dp
LibraryGroup.BY_SOURCE -> R.drawable.ic_browse_filled_24dp
LibraryGroup.UNGROUPED -> R.drawable.ic_ungroup_24dp
else -> R.drawable.ic_label_24dp
}
}
@Composable
private fun ColumnScope.GroupPage(
screenModel: LibrarySettingsScreenModel,
hasCategories: Boolean,
) {
val groups = remember(hasCategories, screenModel.trackServices) {
buildList {
add(LibraryGroup.BY_DEFAULT)
add(LibraryGroup.BY_SOURCE)
add(LibraryGroup.BY_STATUS)
if (screenModel.trackServices.isNotEmpty()) {
add(LibraryGroup.BY_TRACK_STATUS)
}
if (hasCategories) {
add(LibraryGroup.UNGROUPED)
}
}.map {
GroupMode(
it,
LibraryGroup.groupTypeStringRes(it, hasCategories),
groupTypeDrawableRes(it),
)
}
}
groups.fastForEach {
IconItem(
label = stringResource(it.nameRes),
icon = painterResource(it.drawableRes),
selected = it.int == screenModel.grouping,
onClick = {
screenModel.setGrouping(it.int)
},
)
}
}