diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fbceb0b03d..63f16da0ae 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,7 +27,7 @@ android { applicationId = "eu.kanade.tachiyomi" minSdk = AndroidConfig.minSdk targetSdk = AndroidConfig.targetSdk - versionCode = 91 + versionCode = 92 versionName = "0.14.2" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") diff --git a/app/src/main/java/eu/kanade/data/track/TrackRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/track/TrackRepositoryImpl.kt index 703fb450d0..fdf6584240 100644 --- a/app/src/main/java/eu/kanade/data/track/TrackRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/track/TrackRepositoryImpl.kt @@ -9,6 +9,10 @@ class TrackRepositoryImpl( private val handler: DatabaseHandler, ) : TrackRepository { + override suspend fun getTrackById(id: Long): Track? { + return handler.awaitOneOrNull { manga_syncQueries.getTrackById(id, trackMapper) } + } + override suspend fun getTracksByMangaId(mangaId: Long): List { return handler.awaitList { manga_syncQueries.getTracksByMangaId(mangaId, trackMapper) diff --git a/app/src/main/java/eu/kanade/domain/track/interactor/GetTracks.kt b/app/src/main/java/eu/kanade/domain/track/interactor/GetTracks.kt index af854dfb35..1c35e8852e 100644 --- a/app/src/main/java/eu/kanade/domain/track/interactor/GetTracks.kt +++ b/app/src/main/java/eu/kanade/domain/track/interactor/GetTracks.kt @@ -10,6 +10,15 @@ class GetTracks( private val trackRepository: TrackRepository, ) { + suspend fun awaitOne(id: Long): Track? { + return try { + trackRepository.getTrackById(id) + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) + null + } + } + suspend fun await(mangaId: Long): List { return try { trackRepository.getTracksByMangaId(mangaId) diff --git a/app/src/main/java/eu/kanade/domain/track/repository/TrackRepository.kt b/app/src/main/java/eu/kanade/domain/track/repository/TrackRepository.kt index 65e4937f76..75602e9022 100644 --- a/app/src/main/java/eu/kanade/domain/track/repository/TrackRepository.kt +++ b/app/src/main/java/eu/kanade/domain/track/repository/TrackRepository.kt @@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow interface TrackRepository { + suspend fun getTrackById(id: Long): Track? + suspend fun getTracksByMangaId(mangaId: Long): List fun getTracksAsFlow(): Flow> diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/job/DelayedTrackingUpdateJob.kt b/app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt similarity index 84% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/job/DelayedTrackingUpdateJob.kt rename to app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt index 929856599a..952d2493ca 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/job/DelayedTrackingUpdateJob.kt +++ b/app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.data.track.job +package eu.kanade.domain.track.service import android.content.Context import androidx.work.BackoffPolicy @@ -9,10 +9,10 @@ import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.WorkerParameters -import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.model.toDbTrack +import eu.kanade.domain.track.store.DelayedTrackingStore import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.system.logcat @@ -25,7 +25,6 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters) CoroutineWorker(context, workerParams) { override suspend fun doWork(): Result { - val getManga = Injekt.get() val getTracks = Injekt.get() val insertTrack = Injekt.get() @@ -34,10 +33,11 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters) withIOContext { val tracks = delayedTrackingStore.getItems().mapNotNull { - val manga = getManga.await(it.mangaId) ?: return@withIOContext - getTracks.await(manga.id) - .find { track -> track.id == it.trackId } - ?.copy(lastChapterRead = it.lastChapterRead.toDouble()) + val track = getTracks.awaitOne(it.trackId) + if (track == null) { + delayedTrackingStore.remove(it.trackId) + } + track } tracks.forEach { track -> @@ -47,7 +47,7 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters) service.update(track.toDbTrack(), true) insertTrack.await(track) } - delayedTrackingStore.remove(track) + delayedTrackingStore.remove(track.id) } catch (e: Exception) { logcat(LogPriority.ERROR, e) } diff --git a/app/src/main/java/eu/kanade/domain/track/store/DelayedTrackingStore.kt b/app/src/main/java/eu/kanade/domain/track/store/DelayedTrackingStore.kt new file mode 100644 index 0000000000..a973da02e8 --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/track/store/DelayedTrackingStore.kt @@ -0,0 +1,46 @@ +package eu.kanade.domain.track.store + +import android.content.Context +import androidx.core.content.edit +import eu.kanade.domain.track.model.Track +import eu.kanade.tachiyomi.util.system.logcat +import logcat.LogPriority + +class DelayedTrackingStore(context: Context) { + + /** + * Preference file where queued tracking updates are stored. + */ + private val preferences = context.getSharedPreferences("tracking_queue", Context.MODE_PRIVATE) + + fun addItem(track: Track) { + val trackId = track.id.toString() + val lastChapterRead = preferences.getFloat(trackId, 0f) + if (track.lastChapterRead > lastChapterRead) { + logcat(LogPriority.DEBUG) { "Queuing track item: $trackId, last chapter read: ${track.lastChapterRead}" } + preferences.edit { + putFloat(trackId, track.lastChapterRead.toFloat()) + } + } + } + + fun remove(trackId: Long) { + preferences.edit { + remove(trackId.toString()) + } + } + + fun getItems(): List { + return preferences.all.mapNotNull { + DelayedTrackingItem( + trackId = it.key.toLong(), + lastChapterRead = it.value.toString().toFloat(), + ) + } + } + + data class DelayedTrackingItem( + val trackId: Long, + val lastChapterRead: Float, + ) +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt index 85e62ee6d2..3a34c0ec36 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt @@ -20,6 +20,7 @@ import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.library.service.LibraryPreferences import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.track.service.TrackPreferences +import eu.kanade.domain.track.store.DelayedTrackingStore import eu.kanade.domain.ui.UiPreferences import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore import eu.kanade.tachiyomi.core.preference.PreferenceStore @@ -33,7 +34,6 @@ import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadProvider import eu.kanade.tachiyomi.data.saver.ImageSaver import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.job.DelayedTrackingStore import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.network.JavaScriptEngine import eu.kanade.tachiyomi.network.NetworkHelper diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index f934d78813..002c80ac52 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -36,7 +36,6 @@ object Migrations { /** * Performs a migration when the application is updated. * - * @param preferences Preferences of the application. * @return true if a migration is performed, false otherwise. */ fun upgrade( @@ -339,6 +338,16 @@ object Migrations { } } } + if (oldVersion < 92) { + val trackingQueuePref = context.getSharedPreferences("tracking_queue", Context.MODE_PRIVATE) + trackingQueuePref.all.forEach { + val (_, lastChapterRead) = it.value.toString().split(":") + trackingQueuePref.edit { + remove(it.key) + putFloat(it.key, lastChapterRead.toFloat()) + } + } + } return true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/job/DelayedTrackingStore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/job/DelayedTrackingStore.kt deleted file mode 100644 index ba3db4406e..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/job/DelayedTrackingStore.kt +++ /dev/null @@ -1,52 +0,0 @@ -package eu.kanade.tachiyomi.data.track.job - -import android.content.Context -import androidx.core.content.edit -import eu.kanade.domain.track.model.Track -import eu.kanade.tachiyomi.util.system.logcat -import logcat.LogPriority - -class DelayedTrackingStore(context: Context) { - - /** - * Preference file where queued tracking updates are stored. - */ - private val preferences = context.getSharedPreferences("tracking_queue", Context.MODE_PRIVATE) - - fun addItem(track: Track) { - val trackId = track.id.toString() - val (_, lastChapterRead) = preferences.getString(trackId, "0:0.0")!!.split(":") - if (track.lastChapterRead > lastChapterRead.toFloat()) { - val value = "${track.mangaId}:${track.lastChapterRead}" - logcat(LogPriority.DEBUG) { "Queuing track item: $trackId, $value" } - preferences.edit { - putString(trackId, value) - } - } - } - - fun remove(track: Track) { - preferences.edit { - remove(track.id.toString()) - } - } - - @Suppress("UNCHECKED_CAST") - fun getItems(): List { - return (preferences.all as Map).entries - .map { - val (mangaId, lastChapterRead) = it.value.split(":") - DelayedTrackingItem( - trackId = it.key.toLong(), - mangaId = mangaId.toLong(), - lastChapterRead = lastChapterRead.toFloat(), - ) - } - } - - data class DelayedTrackingItem( - val trackId: Long, - val mangaId: Long, - val lastChapterRead: Float, - ) -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 23b7bc6959..76b8cde3ed 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -21,7 +21,9 @@ import eu.kanade.domain.manga.model.toDbManga import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.model.toDbTrack +import eu.kanade.domain.track.service.DelayedTrackingUpdateJob import eu.kanade.domain.track.service.TrackPreferences +import eu.kanade.domain.track.store.DelayedTrackingStore import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.toDomainChapter import eu.kanade.tachiyomi.data.database.models.toDomainManga @@ -32,8 +34,6 @@ import eu.kanade.tachiyomi.data.saver.Image import eu.kanade.tachiyomi.data.saver.ImageSaver import eu.kanade.tachiyomi.data.saver.Location import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.data.track.job.DelayedTrackingStore -import eu.kanade.tachiyomi.data.track.job.DelayedTrackingUpdateJob import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.online.HttpSource diff --git a/app/src/main/sqldelight/data/manga_sync.sq b/app/src/main/sqldelight/data/manga_sync.sq index 93b5b6bb84..63b95da695 100644 --- a/app/src/main/sqldelight/data/manga_sync.sq +++ b/app/src/main/sqldelight/data/manga_sync.sq @@ -25,6 +25,11 @@ getTracks: SELECT * FROM manga_sync; +getTrackById: +SELECT * +FROM manga_sync +WHERE _id = :id; + getTracksByMangaId: SELECT * FROM manga_sync