Fix selecting custom fetch interval not persisting sometimes
This commit is contained in:
parent
bce6af62fc
commit
e6c6c32d81
6 changed files with 43 additions and 47 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -378,14 +378,17 @@ class MangaScreenModel(
|
||||||
|
|
||||||
fun setFetchInterval(manga: Manga, interval: Int) {
|
fun setFetchInterval(manga: Manga, interval: Int) {
|
||||||
screenModelScope.launchIO {
|
screenModelScope.launchIO {
|
||||||
|
if (
|
||||||
updateManga.awaitUpdateFetchInterval(
|
updateManga.awaitUpdateFetchInterval(
|
||||||
// Custom intervals are negative
|
// Custom intervals are negative
|
||||||
manga.copy(fetchInterval = -interval),
|
manga.copy(fetchInterval = -interval),
|
||||||
)
|
)
|
||||||
|
) {
|
||||||
val updatedManga = mangaRepository.getMangaById(manga.id)
|
val updatedManga = mangaRepository.getMangaById(manga.id)
|
||||||
updateSuccessState { it.copy(manga = updatedManga) }
|
updateSuccessState { it.copy(manga = updatedManga) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the manga has any downloads.
|
* Returns true if the manga has any downloads.
|
||||||
|
|
|
@ -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,10 +92,10 @@ 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(
|
val latestDate = ZonedDateTime.ofInstant(
|
||||||
if (manga.lastUpdate > 0) Instant.ofEpochMilli(manga.lastUpdate) else Instant.now(),
|
if (manga.lastUpdate > 0) Instant.ofEpochMilli(manga.lastUpdate) else Instant.now(),
|
||||||
dateTime.zone,
|
dateTime.zone,
|
||||||
|
@ -109,21 +105,18 @@ class FetchInterval(
|
||||||
val timeSinceLatest = ChronoUnit.DAYS.between(latestDate, dateTime).toInt()
|
val timeSinceLatest = ChronoUnit.DAYS.between(latestDate, dateTime).toInt()
|
||||||
val cycle = timeSinceLatest.floorDiv(
|
val cycle = timeSinceLatest.floorDiv(
|
||||||
interval.absoluteValue.takeIf { interval < 0 }
|
interval.absoluteValue.takeIf { interval < 0 }
|
||||||
?: doubleInterval(interval, timeSinceLatest, doubleWhenOver = 10),
|
?: increaseInterval(interval, timeSinceLatest, increaseWhenOver = 10),
|
||||||
)
|
)
|
||||||
latestDate.plusDays((cycle + 1) * interval.toLong()).toEpochSecond(dateTime.offset) * 1000
|
return latestDate.plusDays((cycle + 1) * interval.toLong()).toEpochSecond(dateTime.offset) * 1000
|
||||||
} else {
|
|
||||||
manga.nextUpdate
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Reference in a new issue