Fix selecting custom fetch interval not persisting sometimes

This commit is contained in:
arkon 2024-01-07 15:28:56 -05:00
parent bce6af62fc
commit e6c6c32d81
6 changed files with 43 additions and 47 deletions

View file

@ -81,9 +81,9 @@ class UpdateManga(
dateTime: ZonedDateTime = ZonedDateTime.now(), dateTime: ZonedDateTime = ZonedDateTime.now(),
window: Pair<Long, Long> = fetchInterval.getWindow(dateTime), window: Pair<Long, Long> = fetchInterval.getWindow(dateTime),
): Boolean { ): Boolean {
return fetchInterval.toMangaUpdateOrNull(manga, dateTime, window) return mangaRepository.update(
?.let { mangaRepository.update(it) } fetchInterval.toMangaUpdate(manga, dateTime, window),
?: false )
} }
suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean { suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean {

View file

@ -30,6 +30,7 @@ import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import java.time.Instant import java.time.Instant
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
import kotlin.math.absoluteValue
@Composable @Composable
fun DeleteChaptersDialog( fun DeleteChaptersDialog(
@ -85,7 +86,7 @@ fun SetIntervalDialog(
title = { Text(stringResource(MR.strings.pref_library_update_smart_update)) }, title = { Text(stringResource(MR.strings.pref_library_update_smart_update)) },
text = { text = {
Column { Column {
if (nextUpdateDays != null && nextUpdateDays >= 0) { if (nextUpdateDays != null && nextUpdateDays >= 0 && interval >= 0) {
Text( Text(
stringResource( stringResource(
MR.strings.manga_interval_expected_update, MR.strings.manga_interval_expected_update,
@ -96,8 +97,8 @@ fun SetIntervalDialog(
), ),
pluralStringResource( pluralStringResource(
MR.plurals.day, MR.plurals.day,
count = interval, count = interval.absoluteValue,
interval, interval.absoluteValue,
), ),
), ),
) )
@ -105,7 +106,6 @@ fun SetIntervalDialog(
Spacer(Modifier.height(MaterialTheme.padding.small)) Spacer(Modifier.height(MaterialTheme.padding.small))
} }
// TODO: selecting "1" then doesn't allow for future changes unless defaulting first?
if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) { if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) {
Text(stringResource(MR.strings.manga_interval_custom_amount)) Text(stringResource(MR.strings.manga_interval_custom_amount))

View file

@ -201,14 +201,14 @@ fun MangaActionRow(
onLongClick = onEditCategory, onLongClick = onEditCategory,
) )
MangaActionButton( MangaActionButton(
title = if (nextUpdateDays != null) { title = when (nextUpdateDays) {
pluralStringResource( null -> stringResource(MR.strings.not_applicable)
0 -> stringResource(MR.strings.manga_interval_expected_update_soon)
else -> pluralStringResource(
MR.plurals.day, MR.plurals.day,
count = nextUpdateDays, count = nextUpdateDays,
nextUpdateDays, nextUpdateDays,
) )
} else {
stringResource(MR.strings.not_applicable)
}, },
icon = Icons.Default.HourglassEmpty, icon = Icons.Default.HourglassEmpty,
color = if (isUserIntervalMode) MaterialTheme.colorScheme.primary else defaultActionButtonColor, color = if (isUserIntervalMode) MaterialTheme.colorScheme.primary else defaultActionButtonColor,

View file

@ -378,12 +378,15 @@ class MangaScreenModel(
fun setFetchInterval(manga: Manga, interval: Int) { fun setFetchInterval(manga: Manga, interval: Int) {
screenModelScope.launchIO { screenModelScope.launchIO {
updateManga.awaitUpdateFetchInterval( if (
// Custom intervals are negative updateManga.awaitUpdateFetchInterval(
manga.copy(fetchInterval = -interval), // Custom intervals are negative
) manga.copy(fetchInterval = -interval),
val updatedManga = mangaRepository.getMangaById(manga.id) )
updateSuccessState { it.copy(manga = updatedManga) } ) {
val updatedManga = mangaRepository.getMangaById(manga.id)
updateSuccessState { it.copy(manga = updatedManga) }
}
} }
} }

View file

@ -14,11 +14,11 @@ class FetchInterval(
private val getChaptersByMangaId: GetChaptersByMangaId, private val getChaptersByMangaId: GetChaptersByMangaId,
) { ) {
suspend fun toMangaUpdateOrNull( suspend fun toMangaUpdate(
manga: Manga, manga: Manga,
dateTime: ZonedDateTime, dateTime: ZonedDateTime,
window: Pair<Long, Long>, window: Pair<Long, Long>,
): MangaUpdate? { ): MangaUpdate {
val interval = manga.fetchInterval.takeIf { it < 0 } ?: calculateInterval( val interval = manga.fetchInterval.takeIf { it < 0 } ?: calculateInterval(
chapters = getChaptersByMangaId.await(manga.id, applyScanlatorFilter = true), chapters = getChaptersByMangaId.await(manga.id, applyScanlatorFilter = true),
zone = dateTime.zone, zone = dateTime.zone,
@ -30,11 +30,7 @@ class FetchInterval(
} }
val nextUpdate = calculateNextUpdate(manga, interval, dateTime, currentWindow) val nextUpdate = calculateNextUpdate(manga, interval, dateTime, currentWindow)
return if (manga.nextUpdate == nextUpdate && manga.fetchInterval == interval) { return MangaUpdate(id = manga.id, nextUpdate = nextUpdate, fetchInterval = interval)
null
} else {
MangaUpdate(id = manga.id, nextUpdate = nextUpdate, fetchInterval = interval)
}
} }
fun getWindow(dateTime: ZonedDateTime): Pair<Long, Long> { fun getWindow(dateTime: ZonedDateTime): Pair<Long, Long> {
@ -96,34 +92,31 @@ class FetchInterval(
dateTime: ZonedDateTime, dateTime: ZonedDateTime,
window: Pair<Long, Long>, window: Pair<Long, Long>,
): Long { ): Long {
return if ( if (manga.nextUpdate in window.first.rangeTo(window.second + 1)) {
manga.nextUpdate !in window.first.rangeTo(window.second + 1) || return manga.nextUpdate
manga.fetchInterval == 0
) {
val latestDate = ZonedDateTime.ofInstant(
if (manga.lastUpdate > 0) Instant.ofEpochMilli(manga.lastUpdate) else Instant.now(),
dateTime.zone,
)
.toLocalDate()
.atStartOfDay()
val timeSinceLatest = ChronoUnit.DAYS.between(latestDate, dateTime).toInt()
val cycle = timeSinceLatest.floorDiv(
interval.absoluteValue.takeIf { interval < 0 }
?: doubleInterval(interval, timeSinceLatest, doubleWhenOver = 10),
)
latestDate.plusDays((cycle + 1) * interval.toLong()).toEpochSecond(dateTime.offset) * 1000
} else {
manga.nextUpdate
} }
val latestDate = ZonedDateTime.ofInstant(
if (manga.lastUpdate > 0) Instant.ofEpochMilli(manga.lastUpdate) else Instant.now(),
dateTime.zone,
)
.toLocalDate()
.atStartOfDay()
val timeSinceLatest = ChronoUnit.DAYS.between(latestDate, dateTime).toInt()
val cycle = timeSinceLatest.floorDiv(
interval.absoluteValue.takeIf { interval < 0 }
?: increaseInterval(interval, timeSinceLatest, increaseWhenOver = 10),
)
return latestDate.plusDays((cycle + 1) * interval.toLong()).toEpochSecond(dateTime.offset) * 1000
} }
private fun doubleInterval(delta: Int, timeSinceLatest: Int, doubleWhenOver: Int): Int { private fun increaseInterval(delta: Int, timeSinceLatest: Int, increaseWhenOver: Int): Int {
if (delta >= MAX_INTERVAL) return MAX_INTERVAL if (delta >= MAX_INTERVAL) return MAX_INTERVAL
// double delta again if missed more than 9 check in new delta // double delta again if missed more than 9 check in new delta
val cycle = timeSinceLatest.floorDiv(delta) + 1 val cycle = timeSinceLatest.floorDiv(delta) + 1
return if (cycle > doubleWhenOver) { return if (cycle > increaseWhenOver) {
doubleInterval(delta * 2, timeSinceLatest, doubleWhenOver) increaseInterval(delta * 2, timeSinceLatest, increaseWhenOver)
} else { } else {
delta delta
} }

View file

@ -683,9 +683,9 @@
<string name="display_mode_chapter">Chapter %1$s</string> <string name="display_mode_chapter">Chapter %1$s</string>
<string name="manga_display_interval_title">Estimate every</string> <string name="manga_display_interval_title">Estimate every</string>
<string name="manga_display_modified_interval_title">Set to update every</string> <string name="manga_display_modified_interval_title">Set to update every</string>
<string name="manga_interval_header">Next update</string>
<!-- "... around 2 days" --> <!-- "... around 2 days" -->
<string name="manga_interval_expected_update">Next update expected in around %1$s, checking around every %2$s</string> <string name="manga_interval_expected_update">New chapters predicted to be released in around %1$s, checking around every %2$s.</string>
<string name="manga_interval_expected_update_soon">Soon</string>
<string name="manga_interval_custom_amount">Custom update frequency:</string> <string name="manga_interval_custom_amount">Custom update frequency:</string>
<string name="chapter_downloading_progress">Downloading (%1$d/%2$d)</string> <string name="chapter_downloading_progress">Downloading (%1$d/%2$d)</string>
<string name="chapter_error">Error</string> <string name="chapter_error">Error</string>