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(),
window: Pair<Long, Long> = fetchInterval.getWindow(dateTime),
): Boolean {
return fetchInterval.toMangaUpdateOrNull(manga, dateTime, window)
?.let { mangaRepository.update(it) }
?: false
return mangaRepository.update(
fetchInterval.toMangaUpdate(manga, dateTime, window),
)
}
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 java.time.Instant
import java.time.temporal.ChronoUnit
import kotlin.math.absoluteValue
@Composable
fun DeleteChaptersDialog(
@ -85,7 +86,7 @@ fun SetIntervalDialog(
title = { Text(stringResource(MR.strings.pref_library_update_smart_update)) },
text = {
Column {
if (nextUpdateDays != null && nextUpdateDays >= 0) {
if (nextUpdateDays != null && nextUpdateDays >= 0 && interval >= 0) {
Text(
stringResource(
MR.strings.manga_interval_expected_update,
@ -96,8 +97,8 @@ fun SetIntervalDialog(
),
pluralStringResource(
MR.plurals.day,
count = interval,
interval,
count = interval.absoluteValue,
interval.absoluteValue,
),
),
)
@ -105,7 +106,6 @@ fun SetIntervalDialog(
Spacer(Modifier.height(MaterialTheme.padding.small))
}
// TODO: selecting "1" then doesn't allow for future changes unless defaulting first?
if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) {
Text(stringResource(MR.strings.manga_interval_custom_amount))

View file

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

View file

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

View file

@ -14,11 +14,11 @@ class FetchInterval(
private val getChaptersByMangaId: GetChaptersByMangaId,
) {
suspend fun toMangaUpdateOrNull(
suspend fun toMangaUpdate(
manga: Manga,
dateTime: ZonedDateTime,
window: Pair<Long, Long>,
): MangaUpdate? {
): MangaUpdate {
val interval = manga.fetchInterval.takeIf { it < 0 } ?: calculateInterval(
chapters = getChaptersByMangaId.await(manga.id, applyScanlatorFilter = true),
zone = dateTime.zone,
@ -30,11 +30,7 @@ class FetchInterval(
}
val nextUpdate = calculateNextUpdate(manga, interval, dateTime, currentWindow)
return if (manga.nextUpdate == nextUpdate && manga.fetchInterval == interval) {
null
} else {
MangaUpdate(id = manga.id, nextUpdate = nextUpdate, fetchInterval = interval)
}
return MangaUpdate(id = manga.id, nextUpdate = nextUpdate, fetchInterval = interval)
}
fun getWindow(dateTime: ZonedDateTime): Pair<Long, Long> {
@ -96,34 +92,31 @@ class FetchInterval(
dateTime: ZonedDateTime,
window: Pair<Long, Long>,
): Long {
return if (
manga.nextUpdate !in window.first.rangeTo(window.second + 1) ||
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
if (manga.nextUpdate in window.first.rangeTo(window.second + 1)) {
return 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
// double delta again if missed more than 9 check in new delta
val cycle = timeSinceLatest.floorDiv(delta) + 1
return if (cycle > doubleWhenOver) {
doubleInterval(delta * 2, timeSinceLatest, doubleWhenOver)
return if (cycle > increaseWhenOver) {
increaseInterval(delta * 2, timeSinceLatest, increaseWhenOver)
} else {
delta
}

View file

@ -683,9 +683,9 @@
<string name="display_mode_chapter">Chapter %1$s</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_interval_header">Next update</string>
<!-- "... 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="chapter_downloading_progress">Downloading (%1$d/%2$d)</string>
<string name="chapter_error">Error</string>