Add library filter by intervals
This commit is contained in:
parent
2c032ff70d
commit
6d113c6e12
3 changed files with 88 additions and 2 deletions
|
@ -74,6 +74,7 @@ private fun ColumnScope.FilterPage(
|
||||||
) {
|
) {
|
||||||
val filterDownloaded by screenModel.libraryPreferences.filterDownloaded().collectAsState()
|
val filterDownloaded by screenModel.libraryPreferences.filterDownloaded().collectAsState()
|
||||||
val downloadedOnly by screenModel.preferences.downloadedOnly().collectAsState()
|
val downloadedOnly by screenModel.preferences.downloadedOnly().collectAsState()
|
||||||
|
HeadingItem(R.string.status)
|
||||||
TriStateItem(
|
TriStateItem(
|
||||||
label = stringResource(R.string.label_downloaded),
|
label = stringResource(R.string.label_downloaded),
|
||||||
state = if (downloadedOnly) {
|
state = if (downloadedOnly) {
|
||||||
|
@ -102,12 +103,37 @@ private fun ColumnScope.FilterPage(
|
||||||
state = filterBookmarked,
|
state = filterBookmarked,
|
||||||
onClick = { screenModel.toggleFilter(LibraryPreferences::filterBookmarked) },
|
onClick = { screenModel.toggleFilter(LibraryPreferences::filterBookmarked) },
|
||||||
)
|
)
|
||||||
|
val filterIntervalLate by screenModel.libraryPreferences.filterIntervalLate().collectAsState()
|
||||||
|
TriStateItem(
|
||||||
|
label = stringResource(R.string.action_filter_interval_late),
|
||||||
|
state = filterIntervalLate,
|
||||||
|
onClick = { screenModel.toggleFilter(LibraryPreferences::filterIntervalLate) },
|
||||||
|
)
|
||||||
|
val filterIntervalDropped by screenModel.libraryPreferences.filterIntervalDropped().collectAsState()
|
||||||
|
TriStateItem(
|
||||||
|
label = stringResource(R.string.action_filter_interval_dropped),
|
||||||
|
state = filterIntervalDropped,
|
||||||
|
onClick = { screenModel.toggleFilter(LibraryPreferences::filterIntervalDropped) },
|
||||||
|
)
|
||||||
val filterCompleted by screenModel.libraryPreferences.filterCompleted().collectAsState()
|
val filterCompleted by screenModel.libraryPreferences.filterCompleted().collectAsState()
|
||||||
TriStateItem(
|
TriStateItem(
|
||||||
label = stringResource(R.string.completed),
|
label = stringResource(R.string.completed),
|
||||||
state = filterCompleted,
|
state = filterCompleted,
|
||||||
onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompleted) },
|
onClick = { screenModel.toggleFilter(LibraryPreferences::filterCompleted) },
|
||||||
)
|
)
|
||||||
|
HeadingItem(R.string.intervals_header)
|
||||||
|
val filterIntervalCustom by screenModel.libraryPreferences.filterIntervalCustom().collectAsState()
|
||||||
|
TriStateItem(
|
||||||
|
label = stringResource(R.string.action_filter_interval_custom),
|
||||||
|
state = filterIntervalCustom,
|
||||||
|
onClick = { screenModel.toggleFilter(LibraryPreferences::filterIntervalCustom) },
|
||||||
|
)
|
||||||
|
val filterIntervalLong by screenModel.libraryPreferences.filterIntervalLong().collectAsState()
|
||||||
|
TriStateItem(
|
||||||
|
label = stringResource(R.string.action_filter_interval_long),
|
||||||
|
state = filterIntervalLong,
|
||||||
|
onClick = { screenModel.toggleFilter(LibraryPreferences::filterIntervalLong) },
|
||||||
|
)
|
||||||
|
|
||||||
val trackers = remember { screenModel.trackers }
|
val trackers = remember { screenModel.trackers }
|
||||||
when (trackers.size) {
|
when (trackers.size) {
|
||||||
|
|
|
@ -70,6 +70,8 @@ import tachiyomi.source.local.isLocal
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
import java.util.Date
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Typealias for the library manga, using the category as keys, and list of manga as values.
|
* Typealias for the library manga, using the category as keys, and list of manga as values.
|
||||||
|
@ -181,6 +183,10 @@ class LibraryScreenModel(
|
||||||
val filterUnread = prefs.filterUnread
|
val filterUnread = prefs.filterUnread
|
||||||
val filterStarted = prefs.filterStarted
|
val filterStarted = prefs.filterStarted
|
||||||
val filterBookmarked = prefs.filterBookmarked
|
val filterBookmarked = prefs.filterBookmarked
|
||||||
|
val filterIntervalLong = prefs.filterIntervalLong
|
||||||
|
val filterIntervalLate = prefs.filterIntervalLate
|
||||||
|
val filterIntervalDropped = prefs.filterIntervalDropped
|
||||||
|
val filterIntervalCustom = prefs.filterIntervalCustom
|
||||||
val filterCompleted = prefs.filterCompleted
|
val filterCompleted = prefs.filterCompleted
|
||||||
|
|
||||||
val isNotLoggedInAnyTrack = loggedInTrackers.isEmpty()
|
val isNotLoggedInAnyTrack = loggedInTrackers.isEmpty()
|
||||||
|
@ -189,6 +195,43 @@ class LibraryScreenModel(
|
||||||
val includedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null }
|
val includedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null }
|
||||||
val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty()
|
val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty()
|
||||||
|
|
||||||
|
val filterFnIntervalCustom: (LibraryItem) -> Boolean = {
|
||||||
|
applyFilter(filterIntervalCustom) { it.libraryManga.manga.fetchInterval < 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
val filterFnIntervalLong: (LibraryItem) -> Boolean = {
|
||||||
|
applyFilter(filterIntervalLong) {
|
||||||
|
it.libraryManga.manga.fetchInterval.absoluteValue >= 28
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val now = lazy { Date().time }
|
||||||
|
val filterFnIntervalLate: (LibraryItem) -> Boolean = {
|
||||||
|
applyFilter(filterIntervalLate) {
|
||||||
|
if (it.libraryManga.manga.fetchInterval == 0) { true } else {
|
||||||
|
// get last chapter upload or last fetch if source has no upload time
|
||||||
|
val maxUpload = if (it.libraryManga.latestUpload != 0L) it.libraryManga.latestUpload else it.libraryManga.chapterFetchedAt
|
||||||
|
val lapse = (now.value - maxUpload)
|
||||||
|
val interval = (it.libraryManga.manga.fetchInterval.absoluteValue) * 86400000L
|
||||||
|
// Missed 10 to 20 checks
|
||||||
|
lapse > interval * 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val late2month = lazy { now.value - 56 * 86400000L }
|
||||||
|
val filterFnIntervalDropped: (LibraryItem) -> Boolean = {
|
||||||
|
applyFilter(filterIntervalDropped) {
|
||||||
|
if (it.libraryManga.manga.fetchInterval == 0) { true } else {
|
||||||
|
val maxUpload = if (it.libraryManga.latestUpload != 0L) it.libraryManga.latestUpload else it.libraryManga.chapterFetchedAt
|
||||||
|
val lapse = now.value - maxUpload
|
||||||
|
val interval = (it.libraryManga.manga.fetchInterval.absoluteValue) * 86400000L
|
||||||
|
// Missed 20+ check and late 2 months
|
||||||
|
lapse > interval * 10 && late2month.value >= maxUpload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get last chapter upload or last fetch if source has no upload time
|
||||||
|
}
|
||||||
|
|
||||||
val filterFnDownloaded: (LibraryItem) -> Boolean = {
|
val filterFnDownloaded: (LibraryItem) -> Boolean = {
|
||||||
applyFilter(filterDownloaded) {
|
applyFilter(filterDownloaded) {
|
||||||
it.libraryManga.manga.isLocal() ||
|
it.libraryManga.manga.isLocal() ||
|
||||||
|
@ -231,6 +274,10 @@ class LibraryScreenModel(
|
||||||
filterFnUnread(it) &&
|
filterFnUnread(it) &&
|
||||||
filterFnStarted(it) &&
|
filterFnStarted(it) &&
|
||||||
filterFnBookmarked(it) &&
|
filterFnBookmarked(it) &&
|
||||||
|
filterFnIntervalCustom(it) &&
|
||||||
|
filterFnIntervalLong(it) &&
|
||||||
|
filterFnIntervalLate(it) &&
|
||||||
|
filterFnIntervalDropped(it) &&
|
||||||
filterFnCompleted(it) &&
|
filterFnCompleted(it) &&
|
||||||
filterFnTracking(it)
|
filterFnTracking(it)
|
||||||
}
|
}
|
||||||
|
@ -325,6 +372,10 @@ class LibraryScreenModel(
|
||||||
libraryPreferences.filterStarted().changes(),
|
libraryPreferences.filterStarted().changes(),
|
||||||
libraryPreferences.filterBookmarked().changes(),
|
libraryPreferences.filterBookmarked().changes(),
|
||||||
libraryPreferences.filterCompleted().changes(),
|
libraryPreferences.filterCompleted().changes(),
|
||||||
|
libraryPreferences.filterIntervalLate().changes(),
|
||||||
|
libraryPreferences.filterIntervalDropped().changes(),
|
||||||
|
libraryPreferences.filterIntervalCustom().changes(),
|
||||||
|
libraryPreferences.filterIntervalLong().changes(),
|
||||||
transform = {
|
transform = {
|
||||||
ItemPreferences(
|
ItemPreferences(
|
||||||
downloadBadge = it[0] as Boolean,
|
downloadBadge = it[0] as Boolean,
|
||||||
|
@ -336,6 +387,10 @@ class LibraryScreenModel(
|
||||||
filterStarted = it[6] as TriState,
|
filterStarted = it[6] as TriState,
|
||||||
filterBookmarked = it[7] as TriState,
|
filterBookmarked = it[7] as TriState,
|
||||||
filterCompleted = it[8] as TriState,
|
filterCompleted = it[8] as TriState,
|
||||||
|
filterIntervalLate = it[9] as TriState,
|
||||||
|
filterIntervalDropped = it[10] as TriState,
|
||||||
|
filterIntervalCustom = it[11] as TriState,
|
||||||
|
filterIntervalLong = it[12] as TriState,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -699,6 +754,11 @@ class LibraryScreenModel(
|
||||||
val filterStarted: TriState,
|
val filterStarted: TriState,
|
||||||
val filterBookmarked: TriState,
|
val filterBookmarked: TriState,
|
||||||
val filterCompleted: TriState,
|
val filterCompleted: TriState,
|
||||||
|
val filterIntervalLate: TriState,
|
||||||
|
val filterIntervalDropped: TriState,
|
||||||
|
val filterIntervalCustom: TriState,
|
||||||
|
val filterIntervalLong: TriState,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
<string name="action_filter_unread">Unread</string>
|
<string name="action_filter_unread">Unread</string>
|
||||||
<string name="action_filter_interval_custom">Customized fetch interval</string>
|
<string name="action_filter_interval_custom">Customized fetch interval</string>
|
||||||
<string name="action_filter_interval_long">Fetch monthly (28 days)</string>
|
<string name="action_filter_interval_long">Fetch monthly (28 days)</string>
|
||||||
<string name="action_filter_interval_late">Late 10+ check</string>
|
<string name="action_filter_interval_late">Late 5+ check</string>
|
||||||
<string name="action_filter_interval_dropped">Dropped? Late 20+ and 2 months</string>
|
<string name="action_filter_interval_dropped">Dropped? Late 10+ and 2 months</string>
|
||||||
<string name="action_filter_interval_passed">Passed check period</string>
|
<string name="action_filter_interval_passed">Passed check period</string>
|
||||||
<!-- reserved for #4048 -->
|
<!-- reserved for #4048 -->
|
||||||
<string name="action_filter_empty">Remove filter</string>
|
<string name="action_filter_empty">Remove filter</string>
|
||||||
|
|
Reference in a new issue