Optimize and cleanup library code (mihonapp/mihon#2329)
Co-authored-by: Cuong-Tran <cuongtran.tm@gmail.com> (cherry picked from commit e62cd0e816402303fdf12513816894624f77e208)
This commit is contained in:
parent
74a9182b20
commit
1fd86ca74f
19 changed files with 640 additions and 601 deletions
|
|
@ -23,13 +23,14 @@ ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
|
|||
ktlint_code_style = intellij_idea
|
||||
ktlint_function_naming_ignore_when_annotated_with = Composable
|
||||
ktlint_standard_class-signature = disabled
|
||||
ktlint_standard_comment-wrapping = disabled
|
||||
ktlint_standard_discouraged-comment-location = disabled
|
||||
ktlint_standard_function-expression-body = disabled
|
||||
ktlint_standard_function-signature = disabled
|
||||
ktlint_standard_type-argument-comment = disabled
|
||||
ktlint_standard_type-parameter-comment = disabled
|
||||
|
||||
# Avoid ktlint format messy code from SY
|
||||
ktlint_standard_max-line-length = disabled
|
||||
ktlint_standard_comment-wrapping = disabled
|
||||
ktlint_standard_type-argument-comment = disabled
|
||||
ktlint_standard_value-argument-comment = disabled
|
||||
ktlint_standard_value-parameter-comment = disabled
|
||||
|
|
|
|||
26
CHANGELOG.md
26
CHANGELOG.md
|
|
@ -11,25 +11,6 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- `Other` - for technical stuff.
|
||||
|
||||
## [Unreleased]
|
||||
### Fixes
|
||||
- Fix height of description not being calculated correctly if images are present ([@Secozzi](https://github.com/Secozzi)) ([#2382](https://github.com/mihonapp/mihon/pull/2382))
|
||||
|
||||
## [v0.19.1] - 2025-08-07
|
||||
### Changed
|
||||
- LocalSource now reads ComicInfo.xml file for chapter (if available) to display chapter title, number and scanlator ([@raxod502](https://github.com/radian-software)) ([#2332](https://github.com/mihonapp/mihon/pull/2332))
|
||||
|
||||
### Removed
|
||||
- Predictive back support ([@AntsyLich](https://github.com/AntsyLich)) ([#2362](https://github.com/mihonapp/mihon/pull/2362))
|
||||
|
||||
### Fixes
|
||||
- Fix scrollbar sometimes not showing during scroll or not reaching the bottom with few items ([@anirudhsnayak](https://github.com/anirudhsnayak)) ([#2304](https://github.com/mihonapp/mihon/pull/2304))
|
||||
- Fix local source EPUB files not loading ([@AntsyLich](https://github.com/AntsyLich)) ([#2369](https://github.com/mihonapp/mihon/pull/2369))
|
||||
- Fix title text color in light mode on mass migration list ([@AntsyLich](https://github.com/AntsyLich)) ([#2370](https://github.com/mihonapp/mihon/pull/2370))
|
||||
- Fix 'Default' category showing in library with no user-added categories ([@AntsyLich](https://github.com/AntsyLich)) ([#2371](https://github.com/mihonapp/mihon/pull/2371))
|
||||
- Fix crash when opening filter sheet with an empty library ([@krysanify](https://github.com/krysanify/)) ([#2355](https://github.com/mihonapp/mihon/pull/2355))
|
||||
- Fix mark as read/unread not working for selected library items ([@krysanify](https://github.com/krysanify/)) ([#2355](https://github.com/mihonapp/mihon/pull/2355))
|
||||
|
||||
## [v0.19.0] - 2025-08-04
|
||||
### Added
|
||||
- Add more Kaomoji for empty/error screens ([@ianfhunter](https://github.com/ianfhunter/)) ([#1909](https://github.com/mihonapp/mihon/pull/1909))
|
||||
- Add user manga notes ([@imkunet](https://github.com/imkunet), [@AntsyLich](https://github.com/AntsyLich)) ([#428](https://github.com/mihonapp/mihon/pull/428))
|
||||
|
|
@ -43,7 +24,6 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Add advanced option to always update manga title from source ([@FlaminSarge](https://github.com/FlaminSarge)) ([#1182](https://github.com/mihonapp/mihon/pull/1182))
|
||||
- Full predictive back support ([@AntsyLich](https://github.com/AntsyLich)) ([#2085](https://github.com/mihonapp/mihon/pull/2085))
|
||||
- Add Catppuccin theme (mocha for dark and latte for light, mauve accent) ([@claymorwan](https://github.com/claymorwan/)) ([#2117](https://github.com/mihonapp/mihon/pull/2117))
|
||||
- Manga mass migration ([@AntsyLich](https://github.com/AntsyLich), [@jobobby04](https://github.com/jobobby04)) ([#2110](https://github.com/mihonapp/mihon/pull/2110), [#2336](https://github.com/mihonapp/mihon/pull/2336), [#2338](https://github.com/mihonapp/mihon/pull/2338), [`f119386`](https://github.com/mihonapp/mihon/commit/f119386))
|
||||
|
||||
### Improved
|
||||
- Significantly improve browsing speed (near instantaneous) ([@AntsyLich](https://github.com/AntsyLich)) ([#1946](https://github.com/mihonapp/mihon/pull/1946))
|
||||
|
|
@ -54,7 +34,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Added autofill support to tracker login dialog ([@AntsyLich](https://github.com/AntsyLich)) ([#2069](https://github.com/mihonapp/mihon/pull/2069))
|
||||
- Added option to hide missing chapter count ([@User826](https://github.com/User826), [@AntsyLich](https://github.com/AntsyLich)) ([#2108](https://github.com/mihonapp/mihon/pull/2108))
|
||||
- Use median to determine smart update interval, making it more resilient to long hiatuses ([@Kladki](https://github.com/Kladki)) ([#2251](https://github.com/mihonapp/mihon/pull/2251))
|
||||
- Optimize library code to potentially better handle big user libraries ([@AntsyLich](https://github.com/AntsyLich)) ([#2329](https://github.com/mihonapp/mihon/pull/2329), [#2341](https://github.com/mihonapp/mihon/pull/2341))
|
||||
- Optimize library code to potentially better handle big user libraries ([@AntsyLich](https://github.com/AntsyLich)) ([#2329](https://github.com/mihonapp/mihon/pull/2329))
|
||||
|
||||
### Changed
|
||||
- Display all similarly named duplicates in duplicate manga dialogue ([@NarwhalHorns](https://github.com/NarwhalHorns), [@AntsyLich](https://github.com/AntsyLich)) ([#1861](https://github.com/mihonapp/mihon/pull/1861))
|
||||
|
|
@ -399,9 +379,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Branding to Mihon ([@AntsyLich](https://github.com/AntsyLich))
|
||||
- Minimum supported Android version to 8 ([@AntsyLich](https://github.com/AntsyLich)) ([`dfb3091`](https://github.com/mihonapp/mihon/commit/dfb3091e380dda3e9bfb64bf5c9a685cf3a03d0e))
|
||||
|
||||
[unreleased]: https://github.com/mihonapp/mihon/compare/v0.19.1...main
|
||||
[v0.19.1]: https://github.com/mihonapp/mihon/compare/v0.19.0...v0.19.1
|
||||
[v0.19.0]: https://github.com/mihonapp/mihon/compare/v0.18.0...v0.19.0
|
||||
[unreleased]: https://github.com/mihonapp/mihon/compare/v0.18.0...main
|
||||
[v0.18.0]: https://github.com/mihonapp/mihon/compare/v0.17.1...v0.18.0
|
||||
[v0.17.1]: https://github.com/mihonapp/mihon/compare/v0.17.0...v0.17.1
|
||||
[v0.17.0]: https://github.com/mihonapp/mihon/compare/v0.16.5...v0.17.0
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.util.fastAny
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||
import tachiyomi.domain.library.model.LibraryManga
|
||||
import tachiyomi.domain.manga.model.MangaCover
|
||||
|
|
@ -15,7 +14,7 @@ internal fun LibraryComfortableGrid(
|
|||
items: List<LibraryItem>,
|
||||
columns: Int,
|
||||
contentPadding: PaddingValues,
|
||||
selection: List<LibraryManga>,
|
||||
selection: Set<Long>,
|
||||
onClick: (LibraryManga) -> Unit,
|
||||
onLongClick: (LibraryManga) -> Unit,
|
||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||
|
|
@ -38,7 +37,7 @@ internal fun LibraryComfortableGrid(
|
|||
) { libraryItem ->
|
||||
val manga = libraryItem.libraryManga.manga
|
||||
MangaComfortableGridItem(
|
||||
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
|
||||
isSelected = manga.id in selection,
|
||||
title = manga.title,
|
||||
coverData = MangaCover(
|
||||
mangaId = manga.id,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.util.fastAny
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||
import tachiyomi.domain.library.model.LibraryManga
|
||||
import tachiyomi.domain.manga.model.MangaCover
|
||||
|
|
@ -16,7 +15,7 @@ internal fun LibraryCompactGrid(
|
|||
showTitle: Boolean,
|
||||
columns: Int,
|
||||
contentPadding: PaddingValues,
|
||||
selection: List<LibraryManga>,
|
||||
selection: Set<Long>,
|
||||
onClick: (LibraryManga) -> Unit,
|
||||
onLongClick: (LibraryManga) -> Unit,
|
||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||
|
|
@ -36,7 +35,7 @@ internal fun LibraryCompactGrid(
|
|||
) { libraryItem ->
|
||||
val manga = libraryItem.libraryManga.manga
|
||||
MangaCompactGridItem(
|
||||
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
|
||||
isSelected = manga.id in selection,
|
||||
title = manga.title.takeIf { showTitle },
|
||||
coverData = MangaCover(
|
||||
mangaId = manga.id,
|
||||
|
|
|
|||
|
|
@ -29,22 +29,22 @@ import kotlin.time.Duration.Companion.seconds
|
|||
fun LibraryContent(
|
||||
categories: List<Category>,
|
||||
searchQuery: String?,
|
||||
selection: List<LibraryManga>,
|
||||
selection: Set<Long>,
|
||||
contentPadding: PaddingValues,
|
||||
currentPage: () -> Int,
|
||||
hasActiveFilters: Boolean,
|
||||
showPageTabs: Boolean,
|
||||
onChangeCurrentPage: (Int) -> Unit,
|
||||
onMangaClicked: (Long) -> Unit,
|
||||
onClickManga: (Long) -> Unit,
|
||||
onContinueReadingClicked: ((LibraryManga) -> Unit)?,
|
||||
onToggleSelection: (LibraryManga) -> Unit,
|
||||
onToggleRangeSelection: (LibraryManga) -> Unit,
|
||||
onRefresh: (Category?) -> Boolean,
|
||||
onToggleSelection: (Category, LibraryManga) -> Unit,
|
||||
onToggleRangeSelection: (Category, LibraryManga) -> Unit,
|
||||
onRefresh: () -> Boolean,
|
||||
onGlobalSearchClicked: () -> Unit,
|
||||
getNumberOfMangaForCategory: (Category) -> Int?,
|
||||
getItemCountForCategory: (Category) -> Int?,
|
||||
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
|
||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||
getLibraryForPage: (Int) -> List<LibraryItem>,
|
||||
getItemsForCategory: (Category) -> List<LibraryItem>,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(
|
||||
|
|
@ -55,13 +55,13 @@ fun LibraryContent(
|
|||
) {
|
||||
// SY -->
|
||||
val coercedCurrentPage = remember(categories) { currentPage().coerceIn(0, categories.lastIndex) }
|
||||
val pagerState = rememberPagerState(coercedCurrentPage) { categories.size }
|
||||
// SY <--
|
||||
val pagerState = rememberPagerState(coercedCurrentPage) { categories.size }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
var isRefreshing by remember(pagerState.currentPage) { mutableStateOf(false) }
|
||||
|
||||
if (showPageTabs && categories.size > 1) {
|
||||
if (showPageTabs && categories.isNotEmpty()) {
|
||||
LaunchedEffect(categories) {
|
||||
if (categories.size <= pagerState.currentPage) {
|
||||
pagerState.scrollToPage(categories.size - 1)
|
||||
|
|
@ -70,23 +70,20 @@ fun LibraryContent(
|
|||
LibraryTabs(
|
||||
categories = categories,
|
||||
pagerState = pagerState,
|
||||
getNumberOfMangaForCategory = getNumberOfMangaForCategory,
|
||||
) { scope.launch { pagerState.animateScrollToPage(it) } }
|
||||
}
|
||||
|
||||
val notSelectionMode = selection.isEmpty()
|
||||
val onClickManga = { manga: LibraryManga ->
|
||||
if (notSelectionMode) {
|
||||
onMangaClicked(manga.manga.id)
|
||||
} else {
|
||||
onToggleSelection(manga)
|
||||
getItemCountForCategory = getItemCountForCategory,
|
||||
onTabItemClick = {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(it)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
PullRefresh(
|
||||
refreshing = isRefreshing,
|
||||
enabled = selection.isEmpty(),
|
||||
onRefresh = {
|
||||
val started = onRefresh(categories.getOrNull(currentPage()) ?: return@PullRefresh)
|
||||
val started = onRefresh()
|
||||
if (!started) return@PullRefresh
|
||||
scope.launch {
|
||||
// Fake refresh status but hide it after a second as it's a long running task
|
||||
|
|
@ -95,19 +92,25 @@ fun LibraryContent(
|
|||
isRefreshing = false
|
||||
}
|
||||
},
|
||||
enabled = notSelectionMode,
|
||||
) {
|
||||
LibraryPager(
|
||||
state = pagerState,
|
||||
contentPadding = PaddingValues(bottom = contentPadding.calculateBottomPadding()),
|
||||
hasActiveFilters = hasActiveFilters,
|
||||
selectedManga = selection,
|
||||
selection = selection,
|
||||
searchQuery = searchQuery,
|
||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||
getCategoryForPage = { page -> categories[page] },
|
||||
getDisplayMode = getDisplayMode,
|
||||
getColumnsForOrientation = getColumnsForOrientation,
|
||||
getLibraryForPage = getLibraryForPage,
|
||||
onClickManga = onClickManga,
|
||||
getItemsForCategory = getItemsForCategory,
|
||||
onClickManga = { category, manga ->
|
||||
if (selection.isNotEmpty()) {
|
||||
onToggleSelection(category, manga)
|
||||
} else {
|
||||
onClickManga(manga.manga.id)
|
||||
}
|
||||
},
|
||||
onLongClickManga = onToggleRangeSelection,
|
||||
onClickContinueReading = onContinueReadingClicked,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastAny
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||
import tachiyomi.domain.library.model.LibraryManga
|
||||
import tachiyomi.domain.manga.model.MangaCover
|
||||
|
|
@ -18,7 +17,7 @@ import tachiyomi.presentation.core.util.plus
|
|||
internal fun LibraryList(
|
||||
items: List<LibraryItem>,
|
||||
contentPadding: PaddingValues,
|
||||
selection: List<LibraryManga>,
|
||||
selection: Set<Long>,
|
||||
onClick: (LibraryManga) -> Unit,
|
||||
onLongClick: (LibraryManga) -> Unit,
|
||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||
|
|
@ -45,7 +44,7 @@ internal fun LibraryList(
|
|||
) { libraryItem ->
|
||||
val manga = libraryItem.libraryManga.manga
|
||||
MangaListItem(
|
||||
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
|
||||
isSelected = manga.id in selection,
|
||||
title = manga.title,
|
||||
coverData = MangaCover(
|
||||
mangaId = manga.id,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import androidx.compose.ui.platform.LocalConfiguration
|
|||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.core.preference.PreferenceMutableState
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||
import tachiyomi.domain.category.model.Category
|
||||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||
import tachiyomi.domain.library.model.LibraryManga
|
||||
import tachiyomi.i18n.MR
|
||||
|
|
@ -31,14 +32,15 @@ fun LibraryPager(
|
|||
state: PagerState,
|
||||
contentPadding: PaddingValues,
|
||||
hasActiveFilters: Boolean,
|
||||
selectedManga: List<LibraryManga>,
|
||||
selection: Set<Long>,
|
||||
searchQuery: String?,
|
||||
onGlobalSearchClicked: () -> Unit,
|
||||
getCategoryForPage: (Int) -> Category,
|
||||
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
|
||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||
getLibraryForPage: (Int) -> List<LibraryItem>,
|
||||
onClickManga: (LibraryManga) -> Unit,
|
||||
onLongClickManga: (LibraryManga) -> Unit,
|
||||
getItemsForCategory: (Category) -> List<LibraryItem>,
|
||||
onClickManga: (Category, LibraryManga) -> Unit,
|
||||
onLongClickManga: (Category, LibraryManga) -> Unit,
|
||||
onClickContinueReading: ((LibraryManga) -> Unit)?,
|
||||
) {
|
||||
HorizontalPager(
|
||||
|
|
@ -50,9 +52,10 @@ fun LibraryPager(
|
|||
// To make sure only one offscreen page is being composed
|
||||
return@HorizontalPager
|
||||
}
|
||||
val library = getLibraryForPage(page)
|
||||
val category = getCategoryForPage(page)
|
||||
val items = getItemsForCategory(category)
|
||||
|
||||
if (library.isEmpty()) {
|
||||
if (items.isEmpty()) {
|
||||
LibraryPagerEmptyScreen(
|
||||
searchQuery = searchQuery,
|
||||
hasActiveFilters = hasActiveFilters,
|
||||
|
|
@ -72,12 +75,15 @@ fun LibraryPager(
|
|||
remember { mutableIntStateOf(0) }
|
||||
}
|
||||
|
||||
val onClickManga: (LibraryManga) -> Unit = { onClickManga(category, it) }
|
||||
val onLongClickManga: (LibraryManga) -> Unit = { onLongClickManga(category, it) }
|
||||
|
||||
when (displayMode) {
|
||||
LibraryDisplayMode.List -> {
|
||||
LibraryList(
|
||||
items = library,
|
||||
items = items,
|
||||
contentPadding = contentPadding,
|
||||
selection = selectedManga,
|
||||
selection = selection,
|
||||
onClick = onClickManga,
|
||||
onLongClick = onLongClickManga,
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
|
|
@ -87,11 +93,11 @@ fun LibraryPager(
|
|||
}
|
||||
LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> {
|
||||
LibraryCompactGrid(
|
||||
items = library,
|
||||
items = items,
|
||||
showTitle = displayMode is LibraryDisplayMode.CompactGrid,
|
||||
columns = columns,
|
||||
contentPadding = contentPadding,
|
||||
selection = selectedManga,
|
||||
selection = selection,
|
||||
onClick = onClickManga,
|
||||
onLongClick = onLongClickManga,
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
|
|
@ -101,10 +107,10 @@ fun LibraryPager(
|
|||
}
|
||||
LibraryDisplayMode.ComfortableGrid -> {
|
||||
LibraryComfortableGrid(
|
||||
items = library,
|
||||
items = items,
|
||||
columns = columns,
|
||||
contentPadding = contentPadding,
|
||||
selection = selectedManga,
|
||||
selection = selection,
|
||||
onClick = onClickManga,
|
||||
onLongClick = onLongClickManga,
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
|
|
@ -115,10 +121,10 @@ fun LibraryPager(
|
|||
// KMK -->
|
||||
LibraryDisplayMode.ComfortableGridPanorama -> {
|
||||
LibraryComfortableGrid(
|
||||
items = library,
|
||||
items = items,
|
||||
columns = columns,
|
||||
contentPadding = contentPadding,
|
||||
selection = selectedManga,
|
||||
selection = selection,
|
||||
onClick = onClickManga,
|
||||
onLongClick = onLongClickManga,
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
|
|
|
|||
|
|
@ -18,13 +18,11 @@ import tachiyomi.presentation.core.components.material.TabText
|
|||
internal fun LibraryTabs(
|
||||
categories: List<Category>,
|
||||
pagerState: PagerState,
|
||||
getNumberOfMangaForCategory: (Category) -> Int?,
|
||||
getItemCountForCategory: (Category) -> Int?,
|
||||
onTabItemClick: (Int) -> Unit,
|
||||
) {
|
||||
val currentPageIndex = pagerState.currentPage.coerceAtMost(categories.lastIndex)
|
||||
Column(
|
||||
modifier = Modifier.zIndex(1f),
|
||||
) {
|
||||
Column(modifier = Modifier.zIndex(2f)) {
|
||||
PrimaryScrollableTabRow(
|
||||
selectedTabIndex = currentPageIndex,
|
||||
edgePadding = 0.dp,
|
||||
|
|
@ -39,7 +37,7 @@ internal fun LibraryTabs(
|
|||
text = {
|
||||
TabText(
|
||||
text = category.visualName,
|
||||
badgeCount = getNumberOfMangaForCategory(category),
|
||||
badgeCount = getItemCountForCategory(category),
|
||||
)
|
||||
},
|
||||
unselectedContentColor = MaterialTheme.colorScheme.onSurface,
|
||||
|
|
|
|||
|
|
@ -252,28 +252,23 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||
// KMK <--
|
||||
|
||||
val listToUpdate = if (categoryId != -1L) {
|
||||
libraryManga.filter { it.category == categoryId }
|
||||
libraryManga.filter { categoryId in it.categories }
|
||||
// SY -->
|
||||
} else if (
|
||||
group == LibraryGroup.BY_DEFAULT ||
|
||||
groupLibraryUpdateType == GroupLibraryMode.GLOBAL ||
|
||||
(groupLibraryUpdateType == GroupLibraryMode.ALL_BUT_UNGROUPED && group == LibraryGroup.UNGROUPED)
|
||||
) {
|
||||
val categoriesToUpdate = libraryPreferences.updateCategories().get().map(String::toLong)
|
||||
val includedManga = if (categoriesToUpdate.isNotEmpty()) {
|
||||
libraryManga.filter { it.category in categoriesToUpdate }
|
||||
} else {
|
||||
libraryManga
|
||||
}
|
||||
// SY <--
|
||||
val includedCategories = libraryPreferences.updateCategories().get().map { it.toLong() }.toSet()
|
||||
val excludedCategories = libraryPreferences.updateCategoriesExclude().get().map { it.toLong() }.toSet()
|
||||
|
||||
val categoriesToExclude = libraryPreferences.updateCategoriesExclude().get().map { it.toLong() }
|
||||
val excludedMangaIds = if (categoriesToExclude.isNotEmpty()) {
|
||||
libraryManga.filter { it.category in categoriesToExclude }.map { it.manga.id }
|
||||
} else {
|
||||
emptyList()
|
||||
libraryManga.filter {
|
||||
val included = includedCategories.isEmpty() || it.categories.intersect(includedCategories).isNotEmpty()
|
||||
val excluded = it.categories.intersect(excludedCategories).isNotEmpty()
|
||||
included && !excluded
|
||||
}
|
||||
|
||||
includedManga
|
||||
.filterNot { it.manga.id in excludedMangaIds }
|
||||
// SY -->
|
||||
} else {
|
||||
when (group) {
|
||||
LibraryGroup.BY_TRACK_STATUS -> {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ data class LibraryItem(
|
|||
// KMK <--
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
) {
|
||||
val id: Long = libraryManga.id
|
||||
|
||||
// /**
|
||||
// * Checks if a query matches the manga
|
||||
// *
|
||||
|
|
@ -26,6 +28,9 @@ data class LibraryItem(
|
|||
// */
|
||||
// fun matches(constraint: String): Boolean {
|
||||
// val sourceName by lazy { sourceManager.getOrStub(libraryManga.manga.source).getNameForMangaInfo() }
|
||||
// if (constraint.startsWith("id:", true)) {
|
||||
// return id == constraint.substringAfter("id:").toLongOrNull()
|
||||
// }
|
||||
// return libraryManga.manga.title.contains(constraint, true) ||
|
||||
// (libraryManga.manga.author?.contains(constraint, true) ?: false) ||
|
||||
// (libraryManga.manga.artist?.contains(constraint, true) ?: false) ||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -60,6 +60,7 @@ import exh.recs.batch.RecommendationSearchProgressDialog
|
|||
import exh.recs.batch.SearchStatus
|
||||
import exh.source.MERGED_SOURCE_ID
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
|
|
@ -147,18 +148,15 @@ data object LibraryTab : Tab {
|
|||
defaultCategoryTitle = stringResource(MR.strings.label_default),
|
||||
page = screenModel.activeCategoryIndex,
|
||||
)
|
||||
val tabVisible = state.showCategoryTabs && state.categories.size > 1
|
||||
LibraryToolbar(
|
||||
hasActiveFilters = state.hasActiveFilters,
|
||||
selectedCount = state.selection.size,
|
||||
title = title,
|
||||
onClickUnselectAll = screenModel::clearSelection,
|
||||
onClickSelectAll = { screenModel.selectAll(screenModel.activeCategoryIndex) },
|
||||
onClickInvertSelection = { screenModel.invertSelection(screenModel.activeCategoryIndex) },
|
||||
onClickSelectAll = screenModel::selectAll,
|
||||
onClickInvertSelection = screenModel::invertSelection,
|
||||
onClickFilter = screenModel::showSettingsDialog,
|
||||
onClickRefresh = {
|
||||
onClickRefresh(state.categories[screenModel.activeCategoryIndex.coerceAtMost(state.categories.lastIndex)])
|
||||
},
|
||||
onClickRefresh = { onClickRefresh(screenModel.activeCategory) },
|
||||
onClickGlobalUpdate = { onClickRefresh(null) },
|
||||
onClickOpenRandomManga = {
|
||||
scope.launch {
|
||||
|
|
@ -189,7 +187,8 @@ data object LibraryTab : Tab {
|
|||
Injekt.get<DownloadCache>().invalidateCache()
|
||||
context.toast(MR.strings.download_cache_invalidated)
|
||||
},
|
||||
scrollBehavior = scrollBehavior.takeIf { !tabVisible }, // For scroll overlay when no tab
|
||||
// For scroll overlay when no tab
|
||||
scrollBehavior = scrollBehavior.takeIf { !state.showCategoryTabs },
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
|
|
@ -198,15 +197,15 @@ data object LibraryTab : Tab {
|
|||
onChangeCategoryClicked = screenModel::openChangeCategoryDialog,
|
||||
onMarkAsReadClicked = { screenModel.markReadSelection(true) },
|
||||
onMarkAsUnreadClicked = { screenModel.markReadSelection(false) },
|
||||
onDownloadClicked = screenModel::runDownloadActionSelection
|
||||
.takeIf { state.selection.fastAll { !it.manga.isLocal() } },
|
||||
onDownloadClicked = screenModel::performDownloadAction
|
||||
.takeIf { state.selectedManga.fastAll { !it.isLocal() } },
|
||||
onDeleteClicked = screenModel::openDeleteMangaDialog,
|
||||
// SY -->
|
||||
onClickCleanTitles = screenModel::cleanTitles.takeIf { state.showCleanTitles },
|
||||
onClickMigrate = {
|
||||
val selectedMangaIds = state.selection
|
||||
.filterNot { it.manga.source == MERGED_SOURCE_ID }
|
||||
.map { it.manga.id }
|
||||
val selectedMangaIds = state.selectedManga
|
||||
.filterNot { it.source == MERGED_SOURCE_ID }
|
||||
.map { it.id }
|
||||
screenModel.clearSelection()
|
||||
if (selectedMangaIds.isNotEmpty()) {
|
||||
PreMigrationScreen.navigateToMigration(
|
||||
|
|
@ -225,18 +224,18 @@ data object LibraryTab : Tab {
|
|||
// KMK -->
|
||||
onClickMerge = {
|
||||
if (state.selection.size == 1) {
|
||||
val manga = state.selection.first().manga
|
||||
val manga = state.selectedManga.first()
|
||||
// Invoke merging for this manga
|
||||
screenModel.clearSelection()
|
||||
val smartSearchConfig = SourcesScreen.SmartSearchConfig(manga.title, manga.id)
|
||||
navigator.push(SourcesScreen(smartSearchConfig))
|
||||
} else if (state.selection.isNotEmpty()) {
|
||||
// Invoke multiple merge
|
||||
val selection = state.selection
|
||||
val selectedManga = state.selectedManga
|
||||
screenModel.clearSelection()
|
||||
scope.launchIO {
|
||||
val mergingMangas = selection.filterNot { it.manga.source == MERGED_SOURCE_ID }
|
||||
val mergedMangaId = screenModel.smartSearchMerge(selection)
|
||||
val mergingMangas = selectedManga.filterNot { it.source == MERGED_SOURCE_ID }
|
||||
val mergedMangaId = screenModel.smartSearchMerge(selectedManga.toPersistentList())
|
||||
snackbarHostState.showSnackbar(context.stringResource(SYMR.strings.entry_merged))
|
||||
if (mergedMangaId != null) {
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
|
|
@ -246,7 +245,7 @@ data object LibraryTab : Tab {
|
|||
)
|
||||
if (result == SnackbarResult.ActionPerformed) {
|
||||
screenModel.removeMangas(
|
||||
mangaList = mergingMangas.map { it.manga },
|
||||
mangas = mergingMangas,
|
||||
deleteFromLibrary = true,
|
||||
deleteChapters = false,
|
||||
)
|
||||
|
|
@ -281,7 +280,9 @@ data object LibraryTab : Tab {
|
|||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||
) { contentPadding ->
|
||||
when {
|
||||
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
|
||||
state.isLoading -> {
|
||||
LoadingScreen(Modifier.padding(contentPadding))
|
||||
}
|
||||
state.searchQuery.isNullOrEmpty() && !state.hasActiveFilters && state.isLibraryEmpty -> {
|
||||
val handler = LocalUriHandler.current
|
||||
EmptyScreen(
|
||||
|
|
@ -298,7 +299,7 @@ data object LibraryTab : Tab {
|
|||
}
|
||||
else -> {
|
||||
LibraryContent(
|
||||
categories = state.categories,
|
||||
categories = state.displayedCategories,
|
||||
searchQuery = state.searchQuery,
|
||||
selection = state.selection,
|
||||
contentPadding = contentPadding,
|
||||
|
|
@ -306,7 +307,7 @@ data object LibraryTab : Tab {
|
|||
hasActiveFilters = state.hasActiveFilters,
|
||||
showPageTabs = state.showCategoryTabs || !state.searchQuery.isNullOrEmpty(),
|
||||
onChangeCurrentPage = { screenModel.activeCategoryIndex = it },
|
||||
onMangaClicked = { navigator.push(MangaScreen(it)) },
|
||||
onClickManga = { navigator.push(MangaScreen(it)) },
|
||||
onContinueReadingClicked = { it: LibraryManga ->
|
||||
scope.launchIO {
|
||||
val chapter = screenModel.getNextUnreadChapter(it.manga)
|
||||
|
|
@ -321,18 +322,19 @@ data object LibraryTab : Tab {
|
|||
Unit
|
||||
}.takeIf { state.showMangaContinueButton },
|
||||
onToggleSelection = screenModel::toggleSelection,
|
||||
onToggleRangeSelection = {
|
||||
screenModel.toggleRangeSelection(it)
|
||||
onToggleRangeSelection = { category, manga ->
|
||||
screenModel.toggleRangeSelection(category, manga)
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
},
|
||||
onRefresh = onClickRefresh,
|
||||
onRefresh = { onClickRefresh(screenModel.activeCategory) },
|
||||
onGlobalSearchClicked = {
|
||||
navigator.push(GlobalSearchScreen(screenModel.state.value.searchQuery ?: ""))
|
||||
},
|
||||
getNumberOfMangaForCategory = { state.getMangaCountForCategory(it) },
|
||||
getItemCountForCategory = { state.getItemCountForCategory(it) },
|
||||
getDisplayMode = { screenModel.getDisplayMode() },
|
||||
getColumnsForOrientation = { screenModel.getColumnsPreferenceForCurrentOrientation(it) },
|
||||
) { state.getLibraryItemsByPage(it) }
|
||||
getColumnsForOrientation = { screenModel.getColumnsForOrientation(it) },
|
||||
getItemsForCategory = { state.getItemsForCategory(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -340,20 +342,15 @@ data object LibraryTab : Tab {
|
|||
val onDismissRequest = screenModel::closeDialog
|
||||
when (val dialog = state.dialog) {
|
||||
is LibraryScreenModel.Dialog.SettingsSheet -> run {
|
||||
val category = state.categories.getOrNull(screenModel.activeCategoryIndex)
|
||||
if (category == null) {
|
||||
onDismissRequest()
|
||||
return@run
|
||||
}
|
||||
LibrarySettingsDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
screenModel = settingsScreenModel,
|
||||
category = category,
|
||||
category = screenModel.activeCategory,
|
||||
// SY -->
|
||||
hasCategories = state.categories.fastAny { !it.isSystemCategory },
|
||||
hasCategories = state.libraryData.categories.fastAny { !it.isSystemCategory },
|
||||
// SY <--
|
||||
// KMK -->
|
||||
categories = state.libraryCategories,
|
||||
categories = state.libraryData.categories.filterNot(Category::isSystemCategory),
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,9 @@ package eu.kanade.tachiyomi.ui.stats
|
|||
|
||||
import androidx.compose.ui.util.fastDistinctBy
|
||||
import androidx.compose.ui.util.fastFilter
|
||||
import androidx.compose.ui.util.fastMapNotNull
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.core.util.fastCountNot
|
||||
import eu.kanade.core.util.fastFilterNot
|
||||
import eu.kanade.presentation.more.stats.StatsScreenState
|
||||
import eu.kanade.presentation.more.stats.data.StatsData
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
|
|
@ -108,26 +106,15 @@ class StatsScreenModel(
|
|||
}
|
||||
|
||||
private fun getGlobalUpdateItemCount(libraryManga: List<LibraryManga>): Int {
|
||||
val includedCategories = preferences.updateCategories().get().map { it.toLong() }
|
||||
val includedManga = if (includedCategories.isNotEmpty()) {
|
||||
libraryManga.filter { it.category in includedCategories }
|
||||
} else {
|
||||
libraryManga
|
||||
}
|
||||
|
||||
val excludedCategories = preferences.updateCategoriesExclude().get().map { it.toLong() }
|
||||
val excludedMangaIds = if (excludedCategories.isNotEmpty()) {
|
||||
libraryManga.fastMapNotNull { manga ->
|
||||
manga.id.takeIf { manga.category in excludedCategories }
|
||||
}
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
val includedCategories = preferences.updateCategories().get().map { it.toLong() }.toSet()
|
||||
val excludedCategories = preferences.updateCategoriesExclude().get().map { it.toLong() }.toSet()
|
||||
val updateRestrictions = preferences.autoUpdateMangaRestrictions().get()
|
||||
return includedManga
|
||||
.fastFilterNot { it.manga.id in excludedMangaIds }
|
||||
.fastDistinctBy { it.manga.id }
|
||||
|
||||
return libraryManga.filter {
|
||||
val included = includedCategories.isEmpty() || it.categories.intersect(includedCategories).isNotEmpty()
|
||||
val excluded = it.categories.intersect(excludedCategories).isNotEmpty()
|
||||
included && !excluded
|
||||
}
|
||||
.fastCountNot {
|
||||
(MANGA_NON_COMPLETED in updateRestrictions && it.manga.status.toInt() == SManga.COMPLETED) ||
|
||||
(MANGA_HAS_UNREAD in updateRestrictions && it.unreadCount != 0L) ||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package mihon.core.common.utils
|
||||
|
||||
fun <T> Set<T>.mutate(action: (MutableSet<T>) -> Unit): Set<T> {
|
||||
return toMutableSet().apply(action)
|
||||
}
|
||||
|
|
@ -104,7 +104,7 @@ object MangaMapper {
|
|||
// KMK -->
|
||||
bookmarkedReadCount: Long,
|
||||
// KMK <--
|
||||
category: Long,
|
||||
categories: String,
|
||||
): LibraryManga = LibraryManga(
|
||||
manga = mapManga(
|
||||
id,
|
||||
|
|
@ -136,7 +136,7 @@ object MangaMapper {
|
|||
isSyncing,
|
||||
notes,
|
||||
),
|
||||
category = category,
|
||||
categories = categories.split(",").map { it.toLong() },
|
||||
totalChapters = totalCount,
|
||||
readCount = readCount.toLong(),
|
||||
bookmarkCount = bookmarkCount.toLong(),
|
||||
|
|
|
|||
98
data/src/main/sqldelight/tachiyomi/migrations/41.sqm
Normal file
98
data/src/main/sqldelight/tachiyomi/migrations/41.sqm
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
DROP VIEW IF EXISTS libraryView;
|
||||
|
||||
CREATE VIEW libraryView AS
|
||||
SELECT
|
||||
M.*,
|
||||
coalesce(C.total, 0) AS totalCount,
|
||||
coalesce(C.readCount, 0) AS readCount,
|
||||
coalesce(C.latestUpload, 0) AS latestUpload,
|
||||
coalesce(C.fetchedAt, 0) AS chapterFetchedAt,
|
||||
coalesce(C.lastRead, 0) AS lastRead,
|
||||
coalesce(C.bookmarkCount, 0) AS bookmarkCount,
|
||||
-- KMK -->
|
||||
coalesce(C.bookmarkReadCount, 0) AS bookmarkedReadCount,
|
||||
-- KMK <--
|
||||
coalesce(MC.categories, '0') AS categories
|
||||
FROM mangas M
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
chapters.manga_id,
|
||||
count(*) AS total,
|
||||
sum(read) AS readCount,
|
||||
coalesce(max(chapters.date_upload), 0) AS latestUpload,
|
||||
coalesce(max(history.last_read), 0) AS lastRead,
|
||||
coalesce(max(chapters.date_fetch), 0) AS fetchedAt,
|
||||
sum(chapters.bookmark) AS bookmarkCount,
|
||||
-- KMK -->
|
||||
sum(CASE WHEN chapters.bookmark = 1 AND chapters.read = 1 THEN 1 ELSE 0 END) AS bookmarkReadCount,
|
||||
-- KMK <--
|
||||
excluded_scanlators.scanlator AS ex_scanlator
|
||||
FROM chapters
|
||||
LEFT JOIN excluded_scanlators
|
||||
ON chapters.manga_id = excluded_scanlators.manga_id
|
||||
AND chapters.scanlator = excluded_scanlators.scanlator
|
||||
LEFT JOIN history
|
||||
ON chapters._id = history.chapter_id
|
||||
WHERE ex_scanlator IS NULL
|
||||
GROUP BY chapters.manga_id
|
||||
) AS C
|
||||
ON M._id = C.manga_id
|
||||
LEFT JOIN (
|
||||
SELECT manga_id, group_concat(category_id) AS categories
|
||||
FROM mangas_categories
|
||||
GROUP BY manga_id
|
||||
) AS MC
|
||||
ON MC.manga_id = M._id
|
||||
WHERE M.source <> 6969
|
||||
UNION
|
||||
SELECT
|
||||
M.*,
|
||||
coalesce(C.total, 0) AS totalCount,
|
||||
coalesce(C.readCount, 0) AS readCount,
|
||||
coalesce(C.latestUpload, 0) AS latestUpload,
|
||||
coalesce(C.fetchedAt, 0) AS chapterFetchedAt,
|
||||
coalesce(C.lastRead, 0) AS lastRead,
|
||||
coalesce(C.bookmarkCount, 0) AS bookmarkCount,
|
||||
-- KMK -->
|
||||
coalesce(C.bookmarkReadCount, 0) AS bookmarkedReadCount,
|
||||
-- KMK <--
|
||||
coalesce(MC.categories, '0') AS categories
|
||||
FROM mangas M
|
||||
LEFT JOIN (
|
||||
SELECT merged.manga_id,merged.merge_id
|
||||
FROM merged
|
||||
GROUP BY merged.merge_id
|
||||
) AS ME
|
||||
ON ME.merge_id = M._id
|
||||
LEFT JOIN(
|
||||
SELECT
|
||||
ME.merge_id,
|
||||
count(*) AS total,
|
||||
sum(read) AS readCount,
|
||||
coalesce(max(chapters.date_upload), 0) AS latestUpload,
|
||||
coalesce(max(history.last_read), 0) AS lastRead,
|
||||
coalesce(max(chapters.date_fetch), 0) AS fetchedAt,
|
||||
sum(chapters.bookmark) AS bookmarkCount,
|
||||
-- KMK -->
|
||||
sum(CASE WHEN chapters.bookmark = 1 AND chapters.read = 1 THEN 1 ELSE 0 END) AS bookmarkReadCount,
|
||||
-- KMK <--
|
||||
excluded_scanlators.scanlator AS ex_scanlator
|
||||
FROM chapters
|
||||
LEFT JOIN excluded_scanlators
|
||||
ON chapters.manga_id = excluded_scanlators.manga_id
|
||||
AND chapters.scanlator = excluded_scanlators.scanlator
|
||||
LEFT JOIN history
|
||||
ON chapters._id = history.chapter_id
|
||||
LEFT JOIN merged ME
|
||||
ON ME.manga_id = chapters.manga_id
|
||||
WHERE ex_scanlator IS NULL
|
||||
GROUP BY ME.merge_id
|
||||
) AS C
|
||||
ON M._id = C.merge_id -- ON ME.merge_id = C.merge_id
|
||||
LEFT JOIN (
|
||||
SELECT manga_id, group_concat(category_id) AS categories
|
||||
FROM mangas_categories
|
||||
GROUP BY manga_id
|
||||
) AS MC
|
||||
ON MC.manga_id = M._id
|
||||
WHERE M.source = 6969;
|
||||
|
|
@ -11,9 +11,9 @@ SELECT
|
|||
-- KMK -->
|
||||
coalesce(C.bookmarkReadCount, 0) AS bookmarkedReadCount,
|
||||
-- KMK <--
|
||||
coalesce(MC.category_id, 0) AS category
|
||||
coalesce(MC.categories, '0') AS categories
|
||||
FROM mangas M
|
||||
LEFT JOIN(
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
chapters.manga_id,
|
||||
count(*) AS total,
|
||||
|
|
@ -36,7 +36,11 @@ LEFT JOIN(
|
|||
GROUP BY chapters.manga_id
|
||||
) AS C
|
||||
ON M._id = C.manga_id
|
||||
LEFT JOIN mangas_categories AS MC
|
||||
LEFT JOIN (
|
||||
SELECT manga_id, group_concat(category_id) AS categories
|
||||
FROM mangas_categories
|
||||
GROUP BY manga_id
|
||||
) AS MC
|
||||
ON MC.manga_id = M._id
|
||||
WHERE M.source <> 6969
|
||||
UNION
|
||||
|
|
@ -51,7 +55,7 @@ SELECT
|
|||
-- KMK -->
|
||||
coalesce(C.bookmarkReadCount, 0) AS bookmarkedReadCount,
|
||||
-- KMK <--
|
||||
coalesce(MC.category_id, 0) AS category
|
||||
coalesce(MC.categories, '0') AS categories
|
||||
FROM mangas M
|
||||
LEFT JOIN (
|
||||
SELECT merged.manga_id,merged.merge_id
|
||||
|
|
@ -84,7 +88,11 @@ LEFT JOIN(
|
|||
GROUP BY ME.merge_id
|
||||
) AS C
|
||||
ON M._id = C.merge_id -- ON ME.merge_id = C.merge_id
|
||||
LEFT JOIN mangas_categories AS MC
|
||||
LEFT JOIN (
|
||||
SELECT manga_id, group_concat(category_id) AS categories
|
||||
FROM mangas_categories
|
||||
GROUP BY manga_id
|
||||
) AS MC
|
||||
ON MC.manga_id = M._id
|
||||
WHERE M.source = 6969;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,23 +37,15 @@ class GetUpcomingManga(
|
|||
suspend fun updatingMangas(): List<Manga> {
|
||||
val libraryManga = getLibraryManga.await()
|
||||
|
||||
val categoriesToUpdate = libraryPreferences.updateCategories().get().map(String::toLong)
|
||||
val includedManga = if (categoriesToUpdate.isNotEmpty()) {
|
||||
libraryManga.filter { it.category in categoriesToUpdate }
|
||||
} else {
|
||||
libraryManga
|
||||
}
|
||||
val includedCategories = libraryPreferences.updateCategories().get().map { it.toLong() }.toSet()
|
||||
val excludedCategories = libraryPreferences.updateCategoriesExclude().get().map { it.toLong() }.toSet()
|
||||
|
||||
val categoriesToExclude = libraryPreferences.updateCategoriesExclude().get().map { it.toLong() }
|
||||
val excludedMangaIds = if (categoriesToExclude.isNotEmpty()) {
|
||||
libraryManga.filter { it.category in categoriesToExclude }.map { it.manga.id }
|
||||
} else {
|
||||
emptyList()
|
||||
val listToUpdate = libraryManga.filter {
|
||||
val included = includedCategories.isEmpty() || it.categories.intersect(includedCategories).isNotEmpty()
|
||||
val excluded = it.categories.intersect(excludedCategories).isNotEmpty()
|
||||
included && !excluded
|
||||
}
|
||||
|
||||
val listToUpdate = includedManga
|
||||
.filterNot { it.manga.id in excludedMangaIds }
|
||||
|
||||
val restrictions = libraryPreferences.autoUpdateMangaRestrictions().get()
|
||||
val today = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toEpochSecond() * 1000
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import tachiyomi.domain.manga.model.Manga
|
|||
|
||||
data class LibraryManga(
|
||||
val manga: Manga,
|
||||
val category: Long,
|
||||
val categories: List<Long>,
|
||||
val totalChapters: Long,
|
||||
val readCount: Long,
|
||||
val bookmarkCount: Long,
|
||||
|
|
|
|||
Loading…
Reference in a new issue