From 3ad4f1114adc88189032e4face152db9ed89df55 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 29 Jul 2023 10:29:53 -0400 Subject: [PATCH] Cleanup related to fetch interval display --- .../java/eu/kanade/domain/DomainModule.kt | 4 +-- .../interactor/SyncChaptersWithSource.kt | 2 +- .../domain/manga/interactor/UpdateManga.kt | 8 ++--- .../kanade/presentation/manga/MangaScreen.kt | 25 +++++++------- .../manga/components/MangaInfoHeader.kt | 13 ++++---- .../tachiyomi/data/backup/BackupRestorer.kt | 10 +++--- .../data/library/LibraryUpdateJob.kt | 10 +++--- .../kanade/tachiyomi/ui/manga/MangaScreen.kt | 17 +++++++--- .../tachiyomi/ui/manga/MangaScreenModel.kt | 33 +++++++++---------- .../java/tachiyomi/data/manga/MangaMapper.kt | 2 +- .../data/manga/MangaRepositoryImpl.kt | 4 +-- ...aUpdateInterval.kt => SetFetchInterval.kt} | 20 +++++------ .../tachiyomi/domain/manga/model/Manga.kt | 4 +-- .../domain/manga/model/MangaUpdate.kt | 4 +-- ...ntervalTest.kt => SetFetchIntervalTest.kt} | 22 ++++++------- 15 files changed, 93 insertions(+), 85 deletions(-) rename domain/src/main/java/tachiyomi/domain/manga/interactor/{SetMangaUpdateInterval.kt => SetFetchInterval.kt} (89%) rename domain/src/test/java/tachiyomi/domain/manga/interactor/{SetMangaUpdateIntervalTest.kt => SetFetchIntervalTest.kt} (83%) diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt index cba97c942..2e19e39b6 100644 --- a/app/src/main/java/eu/kanade/domain/DomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt @@ -56,8 +56,8 @@ import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.GetMangaWithChapters import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.interactor.ResetViewerFlags +import tachiyomi.domain.manga.interactor.SetFetchInterval import tachiyomi.domain.manga.interactor.SetMangaChapterFlags -import tachiyomi.domain.manga.interactor.SetMangaUpdateInterval import tachiyomi.domain.manga.repository.MangaRepository import tachiyomi.domain.release.interactor.GetApplicationRelease import tachiyomi.domain.release.service.ReleaseService @@ -101,7 +101,7 @@ class DomainModule : InjektModule { addFactory { GetNextChapters(get(), get(), get()) } addFactory { ResetViewerFlags(get()) } addFactory { SetMangaChapterFlags(get()) } - addFactory { SetMangaUpdateInterval(get()) } + addFactory { SetFetchInterval(get()) } addFactory { SetMangaDefaultChapterFlags(get(), get(), get()) } addFactory { SetMangaViewerFlags(get()) } addFactory { NetworkToLocalManga(get()) } diff --git a/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt b/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt index 24d0bb32a..5d0192ffb 100644 --- a/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt +++ b/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt @@ -138,7 +138,7 @@ class SyncChaptersWithSource( // Return if there's nothing to add, delete or change, avoiding unnecessary db transactions. if (toAdd.isEmpty() && toDelete.isEmpty() && toChange.isEmpty()) { - if (manualFetch || manga.calculateInterval == 0 || manga.nextUpdate < fetchRange.first) { + if (manualFetch || manga.fetchInterval == 0 || manga.nextUpdate < fetchRange.first) { updateManga.awaitUpdateFetchInterval( manga, dbChapters, diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt index da610baa3..f17214dbe 100644 --- a/app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt +++ b/app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt @@ -4,7 +4,7 @@ import eu.kanade.domain.manga.model.hasCustomCover import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.source.model.SManga import tachiyomi.domain.chapter.model.Chapter -import tachiyomi.domain.manga.interactor.SetMangaUpdateInterval +import tachiyomi.domain.manga.interactor.SetFetchInterval import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.MangaUpdate import tachiyomi.domain.manga.repository.MangaRepository @@ -16,7 +16,7 @@ import java.util.Date class UpdateManga( private val mangaRepository: MangaRepository, - private val setMangaUpdateInterval: SetMangaUpdateInterval, + private val setFetchInterval: SetFetchInterval, ) { suspend fun await(mangaUpdate: MangaUpdate): Boolean { @@ -81,9 +81,9 @@ class UpdateManga( manga: Manga, chapters: List, zonedDateTime: ZonedDateTime = ZonedDateTime.now(), - fetchRange: Pair = setMangaUpdateInterval.getCurrentFetchRange(zonedDateTime), + fetchRange: Pair = setFetchInterval.getCurrent(zonedDateTime), ): Boolean { - val updatedManga = setMangaUpdateInterval.updateInterval(manga, chapters, zonedDateTime, fetchRange) + val updatedManga = setFetchInterval.update(manga, chapters, zonedDateTime, fetchRange) return if (updatedManga != null) { mangaRepository.update(updatedManga) } else { diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index 5fe018d80..d52c540ce 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -62,6 +62,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.source.getNameForMangaInfo import eu.kanade.tachiyomi.ui.manga.ChapterItem +import eu.kanade.tachiyomi.ui.manga.FetchInterval import eu.kanade.tachiyomi.ui.manga.MangaScreenModel import eu.kanade.tachiyomi.util.lang.toRelativeString import eu.kanade.tachiyomi.util.system.copyToClipboard @@ -84,7 +85,7 @@ import java.util.Date fun MangaScreen( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, - intervalDisplay: () -> Pair?, + fetchInterval: FetchInterval?, dateFormat: DateFormat, isTabletUi: Boolean, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, @@ -112,7 +113,7 @@ fun MangaScreen( onShareClicked: (() -> Unit)?, onDownloadActionClicked: ((DownloadAction) -> Unit)?, onEditCategoryClicked: (() -> Unit)?, - onEditIntervalClicked: (() -> Unit)?, + onEditFetchIntervalClicked: (() -> Unit)?, onMigrateClicked: (() -> Unit)?, // For bottom action menu @@ -141,7 +142,7 @@ fun MangaScreen( state = state, snackbarHostState = snackbarHostState, dateFormat = dateFormat, - intervalDisplay = intervalDisplay, + fetchInterval = fetchInterval, chapterSwipeStartAction = chapterSwipeStartAction, chapterSwipeEndAction = chapterSwipeEndAction, onBackClicked = onBackClicked, @@ -161,7 +162,7 @@ fun MangaScreen( onShareClicked = onShareClicked, onDownloadActionClicked = onDownloadActionClicked, onEditCategoryClicked = onEditCategoryClicked, - onEditIntervalClicked = onEditIntervalClicked, + onEditIntervalClicked = onEditFetchIntervalClicked, onMigrateClicked = onMigrateClicked, onMultiBookmarkClicked = onMultiBookmarkClicked, onMultiMarkAsReadClicked = onMultiMarkAsReadClicked, @@ -179,7 +180,7 @@ fun MangaScreen( chapterSwipeStartAction = chapterSwipeStartAction, chapterSwipeEndAction = chapterSwipeEndAction, dateFormat = dateFormat, - intervalDisplay = intervalDisplay, + fetchInterval = fetchInterval, onBackClicked = onBackClicked, onChapterClicked = onChapterClicked, onDownloadChapter = onDownloadChapter, @@ -197,7 +198,7 @@ fun MangaScreen( onShareClicked = onShareClicked, onDownloadActionClicked = onDownloadActionClicked, onEditCategoryClicked = onEditCategoryClicked, - onEditIntervalClicked = onEditIntervalClicked, + onEditIntervalClicked = onEditFetchIntervalClicked, onMigrateClicked = onMigrateClicked, onMultiBookmarkClicked = onMultiBookmarkClicked, onMultiMarkAsReadClicked = onMultiMarkAsReadClicked, @@ -216,7 +217,7 @@ private fun MangaScreenSmallImpl( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, dateFormat: DateFormat, - intervalDisplay: () -> Pair?, + fetchInterval: FetchInterval?, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, @@ -389,8 +390,8 @@ private fun MangaScreenSmallImpl( MangaActionRow( favorite = state.manga.favorite, trackingCount = state.trackingCount, - intervalDisplay = intervalDisplay, - isUserIntervalMode = state.manga.calculateInterval < 0, + fetchInterval = fetchInterval, + isUserIntervalMode = state.manga.fetchInterval < 0, onAddToLibraryClicked = onAddToLibraryClicked, onWebViewClicked = onWebViewClicked, onWebViewLongClicked = onWebViewLongClicked, @@ -447,7 +448,7 @@ fun MangaScreenLargeImpl( state: MangaScreenModel.State.Success, snackbarHostState: SnackbarHostState, dateFormat: DateFormat, - intervalDisplay: () -> Pair?, + fetchInterval: FetchInterval?, chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction, chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction, onBackClicked: () -> Unit, @@ -605,8 +606,8 @@ fun MangaScreenLargeImpl( MangaActionRow( favorite = state.manga.favorite, trackingCount = state.trackingCount, - intervalDisplay = intervalDisplay, - isUserIntervalMode = state.manga.calculateInterval < 0, + fetchInterval = fetchInterval, + isUserIntervalMode = state.manga.fetchInterval < 0, onAddToLibraryClicked = onAddToLibraryClicked, onWebViewClicked = onWebViewClicked, onWebViewLongClicked = onWebViewLongClicked, diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt index 01eaec945..821dda5f0 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt @@ -78,6 +78,7 @@ import coil.compose.AsyncImage import eu.kanade.presentation.components.DropdownMenu import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.ui.manga.FetchInterval import eu.kanade.tachiyomi.util.system.copyToClipboard import tachiyomi.domain.manga.model.Manga import tachiyomi.presentation.core.components.material.TextButton @@ -165,7 +166,7 @@ fun MangaActionRow( modifier: Modifier = Modifier, favorite: Boolean, trackingCount: Int, - intervalDisplay: () -> Pair?, + fetchInterval: FetchInterval?, isUserIntervalMode: Boolean, onAddToLibraryClicked: () -> Unit, onWebViewClicked: (() -> Unit)?, @@ -174,7 +175,6 @@ fun MangaActionRow( onEditIntervalClicked: (() -> Unit)?, onEditCategory: (() -> Unit)?, ) { - val interval: Pair? = intervalDisplay() val defaultActionButtonColor = MaterialTheme.colorScheme.onSurface.copy(alpha = .38f) Row(modifier = modifier.padding(start = 16.dp, top = 8.dp, end = 16.dp)) { @@ -189,13 +189,14 @@ fun MangaActionRow( onClick = onAddToLibraryClicked, onLongClick = onEditCategory, ) - if (onEditIntervalClicked != null && interval != null) { + if (onEditIntervalClicked != null && fetchInterval != null) { + val intervalPair = 1.coerceAtLeast(fetchInterval.interval - fetchInterval.leadDays) to (fetchInterval.interval + fetchInterval.followDays) MangaActionButton( title = - if (interval.first == interval.second) { - pluralStringResource(id = R.plurals.day, count = interval.second, interval.second) + if (intervalPair.first == intervalPair.second) { + pluralStringResource(id = R.plurals.day, count = intervalPair.second, intervalPair.second) } else { - pluralStringResource(id = R.plurals.range_interval_day, count = interval.second, interval.first, interval.second) + pluralStringResource(id = R.plurals.range_interval_day, count = intervalPair.second, intervalPair.first, intervalPair.second) }, icon = Icons.Default.HourglassEmpty, color = if (isUserIntervalMode) MaterialTheme.colorScheme.primary else defaultActionButtonColor, diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt index bd568e476..773231cce 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt @@ -14,7 +14,7 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.isActive import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.repository.ChapterRepository -import tachiyomi.domain.manga.interactor.SetMangaUpdateInterval +import tachiyomi.domain.manga.interactor.SetFetchInterval import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.track.model.Track import uy.kohesive.injekt.Injekt @@ -31,10 +31,10 @@ class BackupRestorer( ) { private val updateManga: UpdateManga = Injekt.get() private val chapterRepository: ChapterRepository = Injekt.get() - private val setMangaUpdateInterval: SetMangaUpdateInterval = Injekt.get() + private val setFetchInterval: SetFetchInterval = Injekt.get() private var zonedDateTime = ZonedDateTime.now() - private var currentRange = setMangaUpdateInterval.getCurrentFetchRange(zonedDateTime) + private var currentFetchInterval = setFetchInterval.getCurrent(zonedDateTime) private var backupManager = BackupManager(context) @@ -103,7 +103,7 @@ class BackupRestorer( val backupMaps = backup.backupBrokenSources.map { BackupSource(it.name, it.sourceId) } + backup.backupSources sourceMapping = backupMaps.associate { it.sourceId to it.name } zonedDateTime = ZonedDateTime.now() - currentRange = setMangaUpdateInterval.getCurrentFetchRange(zonedDateTime) + currentFetchInterval = setFetchInterval.getCurrent(zonedDateTime) return coroutineScope { // Restore individual manga @@ -147,7 +147,7 @@ class BackupRestorer( restoreNewManga(updatedManga, chapters, categories, history, tracks, backupCategories) } val updatedChapters = chapterRepository.getChapterByMangaId(restoredManga.id) - updateManga.awaitUpdateFetchInterval(restoredManga, updatedChapters, zonedDateTime, currentRange) + updateManga.awaitUpdateFetchInterval(restoredManga, updatedChapters, zonedDateTime, currentFetchInterval) } catch (e: Exception) { val sourceName = sourceMapping[manga.source] ?: manga.source.toString() errors.add(Date() to "${manga.title} [$sourceName]: ${e.message}") diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index 1d027c196..28ebb22e5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -69,7 +69,7 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_R import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_OUTSIDE_RELEASE_PERIOD import tachiyomi.domain.manga.interactor.GetLibraryManga import tachiyomi.domain.manga.interactor.GetManga -import tachiyomi.domain.manga.interactor.SetMangaUpdateInterval +import tachiyomi.domain.manga.interactor.SetFetchInterval import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.toMangaUpdate import tachiyomi.domain.source.model.SourceNotInstalledException @@ -104,7 +104,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet private val getTracks: GetTracks = Injekt.get() private val insertTrack: InsertTrack = Injekt.get() private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay = Injekt.get() - private val setMangaUpdateInterval: SetMangaUpdateInterval = Injekt.get() + private val setFetchInterval: SetFetchInterval = Injekt.get() private val notifier = LibraryUpdateNotifier(context) @@ -232,8 +232,8 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet val restrictions = libraryPreferences.libraryUpdateMangaRestriction().get() val now = ZonedDateTime.now() - val fetchRange = setMangaUpdateInterval.getCurrentFetchRange(now) - val higherLimit = fetchRange.second + val fetchInterval = setFetchInterval.getCurrent(now) + val higherLimit = fetchInterval.second coroutineScope { mangaToUpdate.groupBy { it.manga.source }.values @@ -272,7 +272,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet else -> { try { - val newChapters = updateManga(manga, now, fetchRange) + val newChapters = updateManga(manga, now, fetchInterval) .sortedByDescending { it.sourceOrder } if (newChapters.isNotEmpty()) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index ac47fe112..58a175532 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -83,6 +83,13 @@ class MangaScreen( val successState = state as MangaScreenModel.State.Success val isHttpSource = remember { successState.source is HttpSource } + val fetchInterval = remember(successState.manga.fetchInterval) { + FetchInterval( + interval = successState.manga.fetchInterval, + leadDays = screenModel.leadDay, + followDays = screenModel.followDay, + ) + } LaunchedEffect(successState.manga, screenModel.source) { if (isHttpSource) { @@ -100,7 +107,7 @@ class MangaScreen( state = successState, snackbarHostState = screenModel.snackbarHostState, dateFormat = screenModel.dateFormat, - intervalDisplay = screenModel::intervalDisplay, + fetchInterval = fetchInterval, isTabletUi = isTabletUi(), chapterSwipeStartAction = screenModel.chapterSwipeStartAction, chapterSwipeEndAction = screenModel.chapterSwipeEndAction, @@ -123,7 +130,7 @@ class MangaScreen( onShareClicked = { shareManga(context, screenModel.manga, screenModel.source) }.takeIf { isHttpSource }, onDownloadActionClicked = screenModel::runDownloadAction.takeIf { !successState.source.isLocalOrStub() }, onEditCategoryClicked = screenModel::showChangeCategoryDialog.takeIf { successState.manga.favorite }, - onEditIntervalClicked = screenModel::showSetMangaIntervalDialog.takeIf { screenModel.isIntervalEnabled && successState.manga.favorite }, + onEditFetchIntervalClicked = screenModel::showSetFetchIntervalDialog.takeIf { screenModel.isUpdateIntervalEnabled && successState.manga.favorite }, onMigrateClicked = { navigator.push(MigrateSearchScreen(successState.manga.id)) }.takeIf { successState.manga.favorite }, onMultiBookmarkClicked = screenModel::bookmarkChapters, onMultiMarkAsReadClicked = screenModel::markChaptersRead, @@ -209,11 +216,11 @@ class MangaScreen( LoadingScreen(Modifier.systemBarsPadding()) } } - is MangaScreenModel.Dialog.SetMangaInterval -> { + is MangaScreenModel.Dialog.SetFetchInterval -> { SetIntervalDialog( - interval = if (dialog.manga.calculateInterval < 0) -dialog.manga.calculateInterval else 0, + interval = if (dialog.manga.fetchInterval < 0) -dialog.manga.fetchInterval else 0, onDismissRequest = onDismissRequest, - onValueChanged = { screenModel.setFetchRangeInterval(dialog.manga, it) }, + onValueChanged = { screenModel.setFetchInterval(dialog.manga, it) }, ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index ae7abe611..e5b828585 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -75,7 +75,6 @@ import tachiyomi.domain.track.interactor.GetTracks import tachiyomi.source.local.isLocal import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import kotlin.math.absoluteValue class MangaScreenModel( val context: Context, @@ -129,9 +128,9 @@ class MangaScreenModel( val dateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get())) private val skipFiltered by readerPreferences.skipFiltered().asState(coroutineScope) - val isIntervalEnabled = LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in libraryPreferences.libraryUpdateMangaRestriction().get() - private val leadDay = libraryPreferences.leadingExpectedDays().get() - private val followDay = libraryPreferences.followingExpectedDays().get() + val isUpdateIntervalEnabled = LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in libraryPreferences.libraryUpdateMangaRestriction().get() + val leadDay = libraryPreferences.leadingExpectedDays().get() + val followDay = libraryPreferences.followingExpectedDays().get() private val selectedPositions: Array = arrayOf(-1, -1) // first and last selected index in list private val selectedChapterIds: HashSet = HashSet() @@ -355,30 +354,23 @@ class MangaScreenModel( } } - fun showSetMangaIntervalDialog() { + fun showSetFetchIntervalDialog() { val manga = successState?.manga ?: return updateSuccessState { - it.copy(dialog = Dialog.SetMangaInterval(manga)) + it.copy(dialog = Dialog.SetFetchInterval(manga)) } } - // TODO: this should be in the state/composables - fun intervalDisplay(): Pair? { - val manga = successState?.manga ?: return null - val effInterval = manga.calculateInterval - return 1.coerceAtLeast(effInterval.absoluteValue - leadDay) to (effInterval.absoluteValue + followDay) - } - - fun setFetchRangeInterval(manga: Manga, newInterval: Int) { + fun setFetchInterval(manga: Manga, newInterval: Int) { val interval = when (newInterval) { // reset interval 0 default to trigger recalculation // only reset if interval is custom, which is negative - 0 -> if (manga.calculateInterval < 0) 0 else manga.calculateInterval + 0 -> if (manga.fetchInterval < 0) 0 else manga.fetchInterval else -> -newInterval } coroutineScope.launchIO { updateManga.awaitUpdateFetchInterval( - manga.copy(calculateInterval = interval), + manga.copy(fetchInterval = interval), successState?.chapters?.map { it.chapter }.orEmpty(), ) val newManga = mangaRepository.getMangaById(mangaId) @@ -983,7 +975,7 @@ class MangaScreenModel( data class ChangeCategory(val manga: Manga, val initialSelection: List>) : Dialog data class DeleteChapters(val chapters: List) : Dialog data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog - data class SetMangaInterval(val manga: Manga) : Dialog + data class SetFetchInterval(val manga: Manga) : Dialog data object SettingsSheet : Dialog data object TrackSheet : Dialog data object FullCover : Dialog @@ -1063,3 +1055,10 @@ data class ChapterItem( ) { val isDownloaded = downloadState == Download.State.DOWNLOADED } + +@Immutable +data class FetchInterval( + val interval: Int, + val leadDays: Int, + val followDays: Int, +) diff --git a/data/src/main/java/tachiyomi/data/manga/MangaMapper.kt b/data/src/main/java/tachiyomi/data/manga/MangaMapper.kt index b021ff0c3..249d85d5f 100644 --- a/data/src/main/java/tachiyomi/data/manga/MangaMapper.kt +++ b/data/src/main/java/tachiyomi/data/manga/MangaMapper.kt @@ -12,7 +12,7 @@ val mangaMapper: (Long, Long, String, String?, String?, String?, List?, favorite = favorite, lastUpdate = lastUpdate ?: 0, nextUpdate = nextUpdate ?: 0, - calculateInterval = calculateInterval.toInt(), + fetchInterval = calculateInterval.toInt(), dateAdded = dateAdded, viewerFlags = viewerFlags, chapterFlags = chapterFlags, diff --git a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt index c7c658f88..eb7e99663 100644 --- a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt +++ b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt @@ -88,7 +88,7 @@ class MangaRepositoryImpl( favorite = manga.favorite, lastUpdate = manga.lastUpdate, nextUpdate = manga.nextUpdate, - calculateInterval = manga.calculateInterval.toLong(), + calculateInterval = manga.fetchInterval.toLong(), initialized = manga.initialized, viewerFlags = manga.viewerFlags, chapterFlags = manga.chapterFlags, @@ -136,7 +136,7 @@ class MangaRepositoryImpl( favorite = value.favorite?.toLong(), lastUpdate = value.lastUpdate, nextUpdate = value.nextUpdate, - calculateInterval = value.calculateInterval?.toLong(), + calculateInterval = value.fetchInterval?.toLong(), initialized = value.initialized?.toLong(), viewer = value.viewerFlags, chapterFlags = value.chapterFlags, diff --git a/domain/src/main/java/tachiyomi/domain/manga/interactor/SetMangaUpdateInterval.kt b/domain/src/main/java/tachiyomi/domain/manga/interactor/SetFetchInterval.kt similarity index 89% rename from domain/src/main/java/tachiyomi/domain/manga/interactor/SetMangaUpdateInterval.kt rename to domain/src/main/java/tachiyomi/domain/manga/interactor/SetFetchInterval.kt index 5ae2ce01c..ca46e5837 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/interactor/SetMangaUpdateInterval.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/interactor/SetFetchInterval.kt @@ -13,32 +13,32 @@ import kotlin.math.absoluteValue const val MAX_GRACE_PERIOD = 28 -class SetMangaUpdateInterval( +class SetFetchInterval( private val libraryPreferences: LibraryPreferences = Injekt.get(), ) { - fun updateInterval( + fun update( manga: Manga, chapters: List, zonedDateTime: ZonedDateTime, fetchRange: Pair, ): MangaUpdate? { - val currentFetchRange = if (fetchRange.first == 0L && fetchRange.second == 0L) { - getCurrentFetchRange(ZonedDateTime.now()) + val currentInterval = if (fetchRange.first == 0L && fetchRange.second == 0L) { + getCurrent(ZonedDateTime.now()) } else { fetchRange } - val interval = manga.calculateInterval.takeIf { it < 0 } ?: calculateInterval(chapters, zonedDateTime) - val nextUpdate = calculateNextUpdate(manga, interval, zonedDateTime, currentFetchRange) + val interval = manga.fetchInterval.takeIf { it < 0 } ?: calculateInterval(chapters, zonedDateTime) + val nextUpdate = calculateNextUpdate(manga, interval, zonedDateTime, currentInterval) - return if (manga.nextUpdate == nextUpdate && manga.calculateInterval == interval) { + return if (manga.nextUpdate == nextUpdate && manga.fetchInterval == interval) { null } else { - MangaUpdate(id = manga.id, nextUpdate = nextUpdate, calculateInterval = interval) + MangaUpdate(id = manga.id, nextUpdate = nextUpdate, fetchInterval = interval) } } - fun getCurrentFetchRange(timeToCal: ZonedDateTime): Pair { + fun getCurrent(timeToCal: ZonedDateTime): Pair { // lead range and the following range depend on if updateOnlyExpectedPeriod set. var followRange = 0 var leadRange = 0 @@ -103,7 +103,7 @@ class SetMangaUpdateInterval( ): Long { return if ( manga.nextUpdate !in fetchRange.first.rangeTo(fetchRange.second + 1) || - manga.calculateInterval == 0 + manga.fetchInterval == 0 ) { val latestDate = ZonedDateTime.ofInstant(Instant.ofEpochMilli(manga.lastUpdate), zonedDateTime.zone).toLocalDate().atStartOfDay() val timeSinceLatest = ChronoUnit.DAYS.between(latestDate, zonedDateTime).toInt() diff --git a/domain/src/main/java/tachiyomi/domain/manga/model/Manga.kt b/domain/src/main/java/tachiyomi/domain/manga/model/Manga.kt index 41db5f827..07451c05b 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/model/Manga.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/model/Manga.kt @@ -10,7 +10,7 @@ data class Manga( val favorite: Boolean, val lastUpdate: Long, val nextUpdate: Long, - val calculateInterval: Int, + val fetchInterval: Int, val dateAdded: Long, val viewerFlags: Long, val chapterFlags: Long, @@ -99,7 +99,7 @@ data class Manga( favorite = false, lastUpdate = 0L, nextUpdate = 0L, - calculateInterval = 0, + fetchInterval = 0, dateAdded = 0L, viewerFlags = 0L, chapterFlags = 0L, diff --git a/domain/src/main/java/tachiyomi/domain/manga/model/MangaUpdate.kt b/domain/src/main/java/tachiyomi/domain/manga/model/MangaUpdate.kt index 2ca97af1a..28a374e87 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/model/MangaUpdate.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/model/MangaUpdate.kt @@ -8,7 +8,7 @@ data class MangaUpdate( val favorite: Boolean? = null, val lastUpdate: Long? = null, val nextUpdate: Long? = null, - val calculateInterval: Int? = null, + val fetchInterval: Int? = null, val dateAdded: Long? = null, val viewerFlags: Long? = null, val chapterFlags: Long? = null, @@ -32,7 +32,7 @@ fun Manga.toMangaUpdate(): MangaUpdate { favorite = favorite, lastUpdate = lastUpdate, nextUpdate = nextUpdate, - calculateInterval = calculateInterval, + fetchInterval = fetchInterval, dateAdded = dateAdded, viewerFlags = viewerFlags, chapterFlags = chapterFlags, diff --git a/domain/src/test/java/tachiyomi/domain/manga/interactor/SetMangaUpdateIntervalTest.kt b/domain/src/test/java/tachiyomi/domain/manga/interactor/SetFetchIntervalTest.kt similarity index 83% rename from domain/src/test/java/tachiyomi/domain/manga/interactor/SetMangaUpdateIntervalTest.kt rename to domain/src/test/java/tachiyomi/domain/manga/interactor/SetFetchIntervalTest.kt index 6cfe8ceb9..d6eadbfab 100644 --- a/domain/src/test/java/tachiyomi/domain/manga/interactor/SetMangaUpdateIntervalTest.kt +++ b/domain/src/test/java/tachiyomi/domain/manga/interactor/SetFetchIntervalTest.kt @@ -10,14 +10,14 @@ import java.time.Duration import java.time.ZonedDateTime @Execution(ExecutionMode.CONCURRENT) -class SetMangaUpdateIntervalTest { +class SetFetchIntervalTest { private val testTime = ZonedDateTime.parse("2020-01-01T00:00:00Z") private var chapter = Chapter.create().copy( dateFetch = testTime.toEpochSecond() * 1000, dateUpload = testTime.toEpochSecond() * 1000, ) - private val setMangaUpdateInterval = SetMangaUpdateInterval(mockk()) + private val setFetchInterval = SetFetchInterval(mockk()) private fun chapterAddTime(chapter: Chapter, duration: Duration): Chapter { val newTime = testTime.plus(duration).toEpochSecond() * 1000 @@ -33,7 +33,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 7 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 7 } @Test @@ -44,7 +44,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 7 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 7 } @Test @@ -60,7 +60,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 7 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 7 } // Default 1 if interval less than 1 @@ -72,7 +72,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 1 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1 } // Normal interval calculation @@ -84,7 +84,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 1 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1 } @Test @@ -95,7 +95,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 2 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 2 } // If interval is decimal, floor to closest integer @@ -107,7 +107,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 1 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1 } @Test @@ -118,7 +118,7 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 1 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1 } // Use fetch time if upload time not available @@ -130,6 +130,6 @@ class SetMangaUpdateIntervalTest { val newChapter = chapterAddTime(chapter, duration).copy(dateUpload = 0L) chapters.add(newChapter) } - setMangaUpdateInterval.calculateInterval(chapters, testTime) shouldBe 1 + setFetchInterval.calculateInterval(chapters, testTime) shouldBe 1 } }