crash fix & add forgotten commit

No idea how I didn't add it yet. Commit: efabe801be
This commit is contained in:
LuftVerbot 2023-11-20 21:15:15 +01:00
parent 18e04b75df
commit 99eea595c0
5 changed files with 132 additions and 82 deletions

View file

@ -30,6 +30,10 @@ import eu.kanade.domain.source.manga.interactor.ToggleMangaSource
import eu.kanade.domain.source.manga.interactor.ToggleMangaSourcePin
import eu.kanade.domain.source.service.SetMigrateSorting
import eu.kanade.domain.source.service.ToggleLanguage
import eu.kanade.domain.track.anime.interactor.RefreshAnimeTracks
import eu.kanade.domain.track.anime.interactor.TrackEpisode
import eu.kanade.domain.track.manga.interactor.RefreshMangaTracks
import eu.kanade.domain.track.manga.interactor.TrackChapter
import tachiyomi.data.category.anime.AnimeCategoryRepositoryImpl
import tachiyomi.data.category.manga.MangaCategoryRepositoryImpl
import tachiyomi.data.entries.anime.AnimeRepositoryImpl
@ -217,12 +221,16 @@ class DomainModule : InjektModule {
addFactory { GetApplicationRelease(get(), get()) }
addSingletonFactory<AnimeTrackRepository> { AnimeTrackRepositoryImpl(get()) }
addFactory { TrackEpisode(get(), get(), get(), get()) }
addFactory { RefreshAnimeTracks(get(), get(), get(), get()) }
addFactory { DeleteAnimeTrack(get()) }
addFactory { GetTracksPerAnime(get()) }
addFactory { GetAnimeTracks(get()) }
addFactory { InsertAnimeTrack(get()) }
addSingletonFactory<MangaTrackRepository> { MangaTrackRepositoryImpl(get()) }
addFactory { TrackChapter(get(), get(), get(), get()) }
addFactory { RefreshMangaTracks(get(), get(), get(), get()) }
addFactory { DeleteMangaTrack(get()) }
addFactory { GetTracksPerManga(get()) }
addFactory { GetMangaTracks(get()) }

View file

@ -0,0 +1,56 @@
package eu.kanade.domain.track.anime.interactor
import android.content.Context
import eu.kanade.domain.track.anime.model.toDbTrack
import eu.kanade.domain.track.anime.service.DelayedAnimeTrackingUpdateJob
import eu.kanade.domain.track.anime.store.DelayedAnimeTrackingStore
import eu.kanade.tachiyomi.data.track.TrackManager
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import logcat.LogPriority
import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.track.anime.interactor.GetAnimeTracks
import tachiyomi.domain.track.anime.interactor.InsertAnimeTrack
class TrackEpisode(
private val getTracks: GetAnimeTracks,
private val trackManager: TrackManager,
private val insertTrack: InsertAnimeTrack,
private val delayedTrackingStore: DelayedAnimeTrackingStore,
) {
suspend fun await(context: Context, animeId: Long, episodeNumber: Double) = coroutineScope {
launchNonCancellable {
val tracks = getTracks.await(animeId)
if (tracks.isEmpty()) return@launchNonCancellable
tracks.mapNotNull { track ->
val service = trackManager.getService(track.syncId)
if (service != null && service.isLoggedIn && episodeNumber > track.lastEpisodeSeen) {
val updatedTrack = track.copy(lastEpisodeSeen = episodeNumber)
async {
runCatching {
try {
service.animeService.update(updatedTrack.toDbTrack(), true)
insertTrack.await(updatedTrack)
} catch (e: Exception) {
delayedTrackingStore.addAnimeItem(updatedTrack)
DelayedAnimeTrackingUpdateJob.setupTask(context)
throw e
}
}
}
} else {
null
}
}
.awaitAll()
.mapNotNull { it.exceptionOrNull() }
.forEach { logcat(LogPriority.INFO, it) }
}
}
}

View file

@ -0,0 +1,56 @@
package eu.kanade.domain.track.manga.interactor
import android.content.Context
import eu.kanade.domain.track.manga.model.toDbTrack
import eu.kanade.domain.track.manga.service.DelayedMangaTrackingUpdateJob
import eu.kanade.domain.track.manga.store.DelayedMangaTrackingStore
import eu.kanade.tachiyomi.data.track.TrackManager
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import logcat.LogPriority
import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.track.manga.interactor.GetMangaTracks
import tachiyomi.domain.track.manga.interactor.InsertMangaTrack
class TrackChapter(
private val getTracks: GetMangaTracks,
private val trackManager: TrackManager,
private val insertTrack: InsertMangaTrack,
private val delayedTrackingStore: DelayedMangaTrackingStore,
) {
suspend fun await(context: Context, mangaId: Long, chapterNumber: Double) = coroutineScope {
launchNonCancellable {
val tracks = getTracks.await(mangaId)
if (tracks.isEmpty()) return@launchNonCancellable
tracks.mapNotNull { track ->
val service = trackManager.getService(track.syncId)
if (service != null && service.isLoggedIn && chapterNumber > track.lastChapterRead) {
val updatedTrack = track.copy(lastChapterRead = chapterNumber)
async {
runCatching {
try {
service.mangaService.update(updatedTrack.toDbTrack(), true)
insertTrack.await(updatedTrack)
} catch (e: Exception) {
delayedTrackingStore.addMangaItem(updatedTrack)
DelayedMangaTrackingUpdateJob.setupTask(context)
throw e
}
}
}
} else {
null
}
}
.awaitAll()
.mapNotNull { it.exceptionOrNull() }
.forEach { logcat(LogPriority.INFO, it) }
}
}
}

View file

@ -10,6 +10,7 @@ import eu.kanade.core.util.asFlow
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.entries.anime.interactor.SetAnimeViewerFlags
import eu.kanade.domain.items.episode.model.toDbEpisode
import eu.kanade.domain.track.anime.interactor.TrackEpisode
import eu.kanade.domain.track.anime.model.toDbTrack
import eu.kanade.domain.track.anime.service.DelayedAnimeTrackingUpdateJob
import eu.kanade.domain.track.anime.store.DelayedAnimeTrackingStore
@ -84,12 +85,11 @@ class PlayerViewModel @JvmOverloads constructor(
private val imageSaver: ImageSaver = Injekt.get(),
private val downloadPreferences: DownloadPreferences = Injekt.get(),
private val trackPreferences: TrackPreferences = Injekt.get(),
private val delayedTrackingStore: DelayedAnimeTrackingStore = Injekt.get(),
private val trackEpisode: TrackEpisode = Injekt.get(),
private val getAnime: GetAnime = Injekt.get(),
private val getNextEpisodes: GetNextEpisodes = Injekt.get(),
private val getEpisodeByAnimeId: GetEpisodeByAnimeId = Injekt.get(),
private val getTracks: GetAnimeTracks = Injekt.get(),
private val insertTrack: InsertAnimeTrack = Injekt.get(),
private val upsertHistory: UpsertAnimeHistory = Injekt.get(),
private val updateEpisode: UpdateEpisode = Injekt.get(),
private val setAnimeViewerFlags: SetAnimeViewerFlags = Injekt.get(),
@ -306,7 +306,6 @@ class PlayerViewModel @JvmOverloads constructor(
}
private var hasTrackers: Boolean = false
private val checkTrackers: (Anime) -> Unit = { anime ->
val tracks = runBlocking { getTracks.await(anime.id) }
hasTrackers = tracks.isNotEmpty()
@ -585,38 +584,11 @@ class PlayerViewModel @JvmOverloads constructor(
if (!trackPreferences.autoUpdateTrack().get()) return
val anime = currentAnime ?: return
val episodeSeen = episode.episode_number.toDouble()
val trackManager = Injekt.get<TrackManager>()
val context = Injekt.get<Application>()
viewModelScope.launchNonCancellable {
getTracks.await(anime.id)
.mapNotNull { track ->
val service = trackManager.getService(track.syncId)
if (service != null && service.isLoggedIn && episodeSeen > track.lastEpisodeSeen) {
val updatedTrack = track.copy(lastEpisodeSeen = episodeSeen)
// We want these to execute even if the presenter is destroyed and leaks
// for a while. The view can still be garbage collected.
async {
runCatching {
if (context.isOnline()) {
service.animeService.update(updatedTrack.toDbTrack(), true)
insertTrack.await(updatedTrack)
} else {
delayedTrackingStore.addAnimeItem(updatedTrack)
DelayedAnimeTrackingUpdateJob.setupTask(context)
}
}
}
} else {
null
}
}
.awaitAll()
.mapNotNull { it.exceptionOrNull() }
.forEach { logcat(LogPriority.INFO, it) }
trackEpisode.await(context, anime.id, episode.episode_number.toDouble())
}
}

View file

@ -11,6 +11,7 @@ import eu.kanade.domain.entries.manga.interactor.SetMangaViewerFlags
import eu.kanade.domain.entries.manga.model.orientationType
import eu.kanade.domain.entries.manga.model.readingModeType
import eu.kanade.domain.items.chapter.model.toDbChapter
import eu.kanade.domain.track.manga.interactor.TrackChapter
import eu.kanade.domain.track.manga.model.toDbTrack
import eu.kanade.domain.track.manga.service.DelayedMangaTrackingUpdateJob
import eu.kanade.domain.track.manga.store.DelayedMangaTrackingStore
@ -98,12 +99,10 @@ class ReaderViewModel @JvmOverloads constructor(
private val basePreferences: BasePreferences = Injekt.get(),
private val downloadPreferences: DownloadPreferences = Injekt.get(),
private val trackPreferences: TrackPreferences = Injekt.get(),
private val delayedTrackingStore: DelayedMangaTrackingStore = Injekt.get(),
private val trackChapter: TrackChapter = Injekt.get(),
private val getManga: GetManga = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
private val getNextChapters: GetNextChapters = Injekt.get(),
private val getTracks: GetMangaTracks = Injekt.get(),
private val insertTrack: InsertMangaTrack = Injekt.get(),
private val upsertHistory: UpsertMangaHistory = Injekt.get(),
private val updateChapter: UpdateChapter = Injekt.get(),
private val setMangaViewerFlags: SetMangaViewerFlags = Injekt.get(),
@ -222,12 +221,6 @@ class ReaderViewModel @JvmOverloads constructor(
.map(::ReaderChapter)
}
private var hasTrackers: Boolean = false
private val checkTrackers: (Manga) -> Unit = { manga ->
val tracks = runBlocking { getTracks.await(manga.id) }
hasTrackers = tracks.isNotEmpty()
}
private val incognitoMode = preferences.incognitoMode().get()
private val downloadAheadAmount = downloadPreferences.autoDownloadWhileReading().get()
@ -286,8 +279,6 @@ class ReaderViewModel @JvmOverloads constructor(
mutableState.update { it.copy(manga = manga) }
if (chapterId == -1L) chapterId = initialChapterId
checkTrackers(manga)
val context = Injekt.get<Application>()
val source = sourceManager.getOrStub(manga.source)
loader = ChapterLoader(
@ -566,18 +557,19 @@ class ReaderViewModel @JvmOverloads constructor(
}
fun flushReadTimer() {
viewModelScope.launchNonCancellable {
updateHistory()
getCurrentChapter()?.let {
viewModelScope.launchNonCancellable {
updateHistory(it)
}
}
}
/**
* Saves the chapter last read history if incognito mode isn't on.
*/
private suspend fun updateHistory() {
private suspend fun updateHistory(readerChapter: ReaderChapter) {
if (incognitoMode) return
val readerChapter = getCurrentChapter() ?: return
val chapterId = readerChapter.chapter.id!!
val readAt = Date()
val sessionReadDuration = chapterReadStartTime?.let { readAt.time - it } ?: 0
@ -887,48 +879,14 @@ class ReaderViewModel @JvmOverloads constructor(
* will run in a background thread and errors are ignored.
*/
private fun updateTrackChapterRead(readerChapter: ReaderChapter) {
if (incognitoMode || !hasTrackers) return
if (incognitoMode) return
if (!trackPreferences.autoUpdateTrack().get()) return
val manga = manga ?: return
val chapterRead = readerChapter.chapter.chapter_number.toDouble()
val trackManager = Injekt.get<TrackManager>()
val context = Injekt.get<Application>()
viewModelScope.launchNonCancellable {
getTracks.await(manga.id)
.mapNotNull { track ->
val service = trackManager.getService(track.syncId)
if (service != null && service.isLoggedIn && chapterRead > track.lastChapterRead) {
val updatedTrack = track.copy(lastChapterRead = chapterRead)
// We want these to execute even if the presenter is destroyed and leaks
// for a while. The view can still be garbage collected.
async {
runCatching {
try {
if (!context.isOnline()) {
error(
"Couldn't update tracker as device is offline",
)
}
service.mangaService.update(updatedTrack.toDbTrack(), true)
insertTrack.await(updatedTrack)
} catch (e: Exception) {
delayedTrackingStore.addMangaItem(updatedTrack)
DelayedMangaTrackingUpdateJob.setupTask(context)
throw e
}
}
}
} else {
null
}
}
.awaitAll()
.mapNotNull { it.exceptionOrNull() }
.forEach { logcat(LogPriority.INFO, it) }
trackChapter.await(context, manga.id, readerChapter.chapter.chapter_number.toDouble())
}
}