From d0c802b6ea2cd0dbfb54df28edf285c48bf387eb Mon Sep 17 00:00:00 2001 From: Jays2Kings Date: Mon, 22 Mar 2021 02:23:35 -0400 Subject: [PATCH] Add more details when first adding a tracker Such as last read chapter Completed status Start Date (if applicable) End Date (also if applicable) --- .../data/database/queries/ChapterQueries.kt | 6 ++- .../tachiyomi/data/track/TrackService.kt | 44 +++++++++++++++++++ .../tachiyomi/data/track/anilist/Anilist.kt | 4 ++ .../data/track/anilist/AnilistApi.kt | 8 ++-- .../tachiyomi/data/track/bangumi/Bangumi.kt | 5 +++ .../tachiyomi/data/track/kitsu/Kitsu.kt | 3 ++ .../data/track/myanimelist/MyAnimeList.kt | 4 ++ .../data/track/shikimori/Shikimori.kt | 5 +++ .../ui/manga/MangaDetailsPresenter.kt | 4 +- 9 files changed, 76 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt index dd98b3f7e7..66d1875278 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt @@ -19,13 +19,15 @@ import java.util.Date interface ChapterQueries : DbProvider { - fun getChapters(manga: Manga) = db.get() + fun getChapters(manga: Manga) = getChapters(manga.id) + + fun getChapters(mangaId: Long?) = db.get() .listOfObjects(Chapter::class.java) .withQuery( Query.builder() .table(ChapterTable.TABLE) .where("${ChapterTable.COL_MANGA_ID} = ?") - .whereArgs(manga.id) + .whereArgs(mangaId) .build() ) .prepare() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt index f753e663a8..717b44b4da 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt @@ -3,10 +3,15 @@ package eu.kanade.tachiyomi.data.track import androidx.annotation.CallSuper import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.network.NetworkHelper +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.ui.manga.track.SetTrackReadingDatesDialog +import eu.kanade.tachiyomi.util.system.executeOnIO import okhttp3.OkHttpClient import uy.kohesive.injekt.injectLazy @@ -14,6 +19,7 @@ abstract class TrackService(val id: Int) { val preferences: PreferencesHelper by injectLazy() val networkService: NetworkHelper by injectLazy() + val db: DatabaseHelper by injectLazy() open fun canRemoveFromService() = false open val client: OkHttpClient get() = networkService.client @@ -34,6 +40,8 @@ abstract class TrackService(val id: Int) { abstract fun isCompletedStatus(index: Int): Boolean + abstract fun completedStatus(): Int + abstract fun getStatus(status: Int): String abstract fun getGlobalStatus(status: Int): String @@ -77,3 +85,39 @@ abstract class TrackService(val id: Int) { preferences.setTrackCredentials(this, username, password) } } + +suspend fun TrackService.updateNewTrackInfo(track: Track) { + val allRead = db.getManga(track.manga_id).executeOnIO()?.status == SManga.COMPLETED && + db.getChapters(track.manga_id).executeOnIO().all { it.read } + if (supportsReadingDates) { + track.started_reading_date = getStartDate(track) + track.finished_reading_date = getCompletedDate(track, allRead) + } + track.last_chapter_read = getLastChapterRead(track) + if (allRead) { + track.status = completedStatus() + } +} + +suspend fun TrackService.getStartDate(track: Track): Long { + if (db.getChapters(track.manga_id).executeOnIO().any { it.read }) { + val chapters = db.getHistoryByMangaId(track.manga_id).executeOnIO() + val date = chapters.minOfOrNull { it.last_read } ?: return 0L + return if (date <= 0L) 0L else date + } + return 0L +} + +suspend fun TrackService.getCompletedDate(track: Track, allRead: Boolean): Long { + if (allRead) { + val chapters = db.getHistoryByMangaId(track.manga_id).executeOnIO() + val date = chapters.maxOfOrNull { it.last_read } ?: return 0L + return if (date <= 0L) 0L else date + } + return 0L +} + +suspend fun TrackService.getLastChapterRead(track: Track): Int { + val chapters = db.getChapters(track.manga_id).executeOnIO() + return chapters.filter { it.read }.minByOrNull { it.source_order }?.chapter_number?.toInt() ?: 0 +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt index 94bc962526..f1dfb262a2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt @@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.updateNewTrackInfo import timber.log.Timber import uy.kohesive.injekt.injectLazy @@ -44,6 +45,8 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) { override fun isCompletedStatus(index: Int) = getStatusList()[index] == COMPLETED + override fun completedStatus() = COMPLETED + override fun getStatus(status: Int): String = with(context) { when (status) { READING -> getString(R.string.reading) @@ -127,6 +130,7 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) { override suspend fun add(track: Track): Track { track.score = DEFAULT_SCORE.toFloat() track.status = DEFAULT_STATUS + updateNewTrackInfo(track) return api.addLibManga(track) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt index fd1c2d0b6c..6ccd635758 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt @@ -38,7 +38,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) { val variables = jsonObject( "mangaId" to track.media_id, "progress" to track.last_chapter_read, - "status" to track.toAnilistStatus() + "status" to track.toAnilistStatus(), + "startedAt" to createDate(track.started_reading_date), + "completedAt" to createDate(track.finished_reading_date) ) val payload = jsonObject( "query" to addToLibraryQuery(), @@ -264,8 +266,8 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) { fun addToLibraryQuery() = """ - |mutation AddManga(${'$'}mangaId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus) { - |SaveMediaListEntry (mediaId: ${'$'}mangaId, progress: ${'$'}progress, status: ${'$'}status) { + |mutation AddManga(${'$'}mangaId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}startedAt: FuzzyDateInput, ${'$'}completedAt: FuzzyDateInput) { + |SaveMediaListEntry (mediaId: ${'$'}mangaId, progress: ${'$'}progress, status: ${'$'}status, startedAt: ${'$'}startedAt, completedAt: ${'$'}completedAt) { | id | status |} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt index 96d92c4a23..6a4cadb9ca 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt @@ -8,6 +8,8 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.model.TrackSearch +import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList +import eu.kanade.tachiyomi.data.track.updateNewTrackInfo import timber.log.Timber import uy.kohesive.injekt.injectLazy @@ -40,6 +42,7 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) { override suspend fun add(track: Track): Track { track.score = DEFAULT_SCORE.toFloat() track.status = DEFAULT_STATUS + updateNewTrackInfo(track) api.addLibManga(track) return update(track) } @@ -83,6 +86,8 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) { override fun isCompletedStatus(index: Int) = getStatusList()[index] == COMPLETED + override fun completedStatus(): Int = MyAnimeList.COMPLETED + override fun getStatus(status: Int): String = with(context) { when (status) { READING -> getString(R.string.reading) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt index cf1bee44b5..e7972eb220 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt @@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.model.TrackSearch +import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList import timber.log.Timber import uy.kohesive.injekt.injectLazy import java.text.DecimalFormat @@ -48,6 +49,8 @@ class Kitsu(private val context: Context, id: Int) : TrackService(id) { override fun isCompletedStatus(index: Int) = getStatusList()[index] == COMPLETED + override fun completedStatus(): Int = MyAnimeList.COMPLETED + override fun getStatus(status: Int): String = with(context) { when (status) { READING -> getString(R.string.currently_reading) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt index 6af160cdeb..9990293e3c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt @@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.model.TrackSearch +import eu.kanade.tachiyomi.data.track.updateNewTrackInfo import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -58,6 +59,8 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) { override fun isCompletedStatus(index: Int) = getStatusList()[index] == COMPLETED + override fun completedStatus(): Int = COMPLETED + override fun getScoreList(): List { return IntRange(0, 10).map(Int::toString) } @@ -69,6 +72,7 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) { override suspend fun add(track: Track): Track { track.status = READING track.score = 0F + updateNewTrackInfo(track) return api.updateItem(track) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt index 432de40d01..3fe6245154 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt @@ -7,6 +7,8 @@ import com.google.gson.Gson import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.track.TrackService +import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList +import eu.kanade.tachiyomi.data.track.updateNewTrackInfo import timber.log.Timber import uy.kohesive.injekt.injectLazy @@ -31,6 +33,8 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) { override fun isCompletedStatus(index: Int) = getStatusList()[index] == COMPLETED + override fun completedStatus(): Int = MyAnimeList.COMPLETED + override fun getStatus(status: Int): String = with(context) { when (status) { READING -> getString(R.string.reading) @@ -73,6 +77,7 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) { override suspend fun add(track: Track): Track { track.score = DEFAULT_SCORE.toFloat() track.status = DEFAULT_STATUS + updateNewTrackInfo(track) return api.addLibManga(track, getUsername()) } override suspend fun bind(track: Track): Track { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt index 730879bfa0..ee2acfeea3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt @@ -899,8 +899,8 @@ class MangaDetailsPresenter( fun getSuggestedDate(readingDate: SetTrackReadingDatesDialog.ReadingDate): Long? { val chapters = db.getHistoryByMangaId(manga.id ?: 0L).executeAsBlocking() val date = when (readingDate) { - SetTrackReadingDatesDialog.ReadingDate.Start -> chapters.minByOrNull { it.last_read }?.last_read - SetTrackReadingDatesDialog.ReadingDate.Finish -> chapters.maxByOrNull { it.last_read }?.last_read + SetTrackReadingDatesDialog.ReadingDate.Start -> chapters.minOfOrNull { it.last_read } + SetTrackReadingDatesDialog.ReadingDate.Finish -> chapters.maxOfOrNull { it.last_read } } ?: return null return if (date <= 0L) null else date }