Fix scrobbling chapter index
This commit is contained in:
@@ -109,10 +109,7 @@ class HistoryRepository @Inject constructor(
|
||||
),
|
||||
)
|
||||
trackingRepository.syncWithHistory(manga, chapterId)
|
||||
val chapter = manga.chapters?.findById(chapterId)
|
||||
if (chapter != null) {
|
||||
scrobblers.forEach { it.tryScrobble(manga.id, chapter) }
|
||||
}
|
||||
scrobblers.forEach { it.tryScrobble(manga, chapterId) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.parsers.exception.GraphQLException
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.util.await
|
||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
||||
@@ -154,11 +153,11 @@ class AniListRepository @Inject constructor(
|
||||
saveRate(response.getJSONObject("data").getJSONObject("SaveMediaListEntry"), mangaId)
|
||||
}
|
||||
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: MangaChapter) {
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: Int) {
|
||||
val response = doRequest(
|
||||
REQUEST_MUTATION,
|
||||
"""
|
||||
SaveMediaListEntry(id: $rateId, progress: ${chapter.number}) {
|
||||
SaveMediaListEntry(id: $rateId, progress: $chapter) {
|
||||
id
|
||||
mediaId
|
||||
status
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.scrobbling.anilist.domain
|
||||
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.scrobbling.anilist.data.AniListRepository
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.Scrobbler
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
@@ -12,7 +13,8 @@ import javax.inject.Singleton
|
||||
class AniListScrobbler @Inject constructor(
|
||||
private val repository: AniListRepository,
|
||||
db: MangaDatabase,
|
||||
) : Scrobbler(db, ScrobblerService.ANILIST, repository) {
|
||||
mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) : Scrobbler(db, ScrobblerService.ANILIST, repository, mangaRepositoryFactory) {
|
||||
|
||||
init {
|
||||
statuses[ScrobblingStatus.PLANNED] = "PLANNING"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.koitharu.kotatsu.scrobbling.common.data
|
||||
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerMangaInfo
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser
|
||||
@@ -27,7 +26,7 @@ interface ScrobblerRepository {
|
||||
|
||||
suspend fun createRate(mangaId: Long, scrobblerMangaId: Long)
|
||||
|
||||
suspend fun updateRate(rateId: Int, mangaId: Long, chapter: MangaChapter)
|
||||
suspend fun updateRate(rateId: Int, mangaId: Long, chapter: Int)
|
||||
|
||||
suspend fun updateRate(rateId: Int, mangaId: Long, rating: Float, status: String?, comment: String?)
|
||||
}
|
||||
|
||||
@@ -11,10 +11,12 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.model.findById
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.core.util.ext.findKeyByValue
|
||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||
import org.koitharu.kotatsu.core.util.ext.sanitize
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository
|
||||
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblingEntity
|
||||
@@ -30,6 +32,7 @@ abstract class Scrobbler(
|
||||
protected val db: MangaDatabase,
|
||||
val scrobblerService: ScrobblerService,
|
||||
private val repository: ScrobblerRepository,
|
||||
private val mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) {
|
||||
|
||||
private val infoCache = LongSparseArray<ScrobblerMangaInfo>()
|
||||
@@ -68,9 +71,23 @@ abstract class Scrobbler(
|
||||
repository.createRate(mangaId, targetId)
|
||||
}
|
||||
|
||||
suspend fun scrobble(mangaId: Long, chapter: MangaChapter) {
|
||||
val entity = db.getScrobblingDao().find(scrobblerService.id, mangaId) ?: return
|
||||
repository.updateRate(entity.id, entity.mangaId, chapter)
|
||||
suspend fun scrobble(manga: Manga, chapterId: Long) {
|
||||
var chapters = manga.chapters
|
||||
if (chapters.isNullOrEmpty()) {
|
||||
chapters = mangaRepositoryFactory.create(manga.source).getDetails(manga).chapters
|
||||
}
|
||||
requireNotNull(chapters)
|
||||
val chapter = checkNotNull(chapters.findById(chapterId)) {
|
||||
"Chapter $chapterId not found in this manga"
|
||||
}
|
||||
val number = if (chapter.number > 0f) {
|
||||
chapter.number.toInt()
|
||||
} else {
|
||||
chapters = chapters.filter { x -> x.branch == chapter.branch }
|
||||
chapters.indexOf(chapter) + 1
|
||||
}
|
||||
val entity = db.getScrobblingDao().find(scrobblerService.id, manga.id) ?: return
|
||||
repository.updateRate(entity.id, entity.mangaId, number)
|
||||
}
|
||||
|
||||
suspend fun getScrobblingInfoOrNull(mangaId: Long): ScrobblingInfo? {
|
||||
@@ -137,9 +154,9 @@ abstract class Scrobbler(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Scrobbler.tryScrobble(mangaId: Long, chapter: MangaChapter): Boolean {
|
||||
suspend fun Scrobbler.tryScrobble(manga: Manga, chapterId: Long): Boolean {
|
||||
return runCatchingCancellable {
|
||||
scrobble(mangaId, chapter)
|
||||
scrobble(manga, chapterId)
|
||||
}.onFailure {
|
||||
it.printStackTraceDebug()
|
||||
}.isSuccess
|
||||
|
||||
@@ -14,10 +14,8 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.findById
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
||||
import org.koitharu.kotatsu.core.parser.MangaIntent
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||
import org.koitharu.kotatsu.core.util.ext.call
|
||||
@@ -40,7 +38,6 @@ class ScrobblingSelectorViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
scrobblers: Set<@JvmSuppressWildcards Scrobbler>,
|
||||
private val historyRepository: HistoryRepository,
|
||||
private val mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) : BaseViewModel() {
|
||||
|
||||
val manga = savedStateHandle.require<ParcelableManga>(MangaIntent.KEY_MANGA).manga
|
||||
@@ -164,15 +161,10 @@ class ScrobblingSelectorViewModel @Inject constructor(
|
||||
comment = prevInfo?.comment,
|
||||
)
|
||||
if (history != null) {
|
||||
val chapter = mangaRepositoryFactory.create(manga.source)
|
||||
.getDetails(manga)
|
||||
.chapters?.findById(history.chapterId)
|
||||
if (chapter != null) {
|
||||
currentScrobbler.scrobble(
|
||||
mangaId = manga.id,
|
||||
chapter = chapter,
|
||||
)
|
||||
}
|
||||
currentScrobbler.scrobble(
|
||||
manga = manga,
|
||||
chapterId = history.chapterId,
|
||||
)
|
||||
}
|
||||
onClose.call(Unit)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.util.ext.parseJsonOrNull
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.util.await
|
||||
import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault
|
||||
import org.koitharu.kotatsu.parsers.util.json.getIntOrDefault
|
||||
@@ -161,13 +160,13 @@ class KitsuRepository(
|
||||
saveRate(response, mangaId)
|
||||
}
|
||||
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: MangaChapter) {
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: Int) {
|
||||
val payload = JSONObject()
|
||||
payload.putJO("data") {
|
||||
put("type", "libraryEntries")
|
||||
put("id", rateId)
|
||||
putJO("attributes") {
|
||||
put("progress", chapter.number.toInt()) // TODO
|
||||
put("progress", chapter)
|
||||
}
|
||||
}
|
||||
val request = Request.Builder()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.scrobbling.kitsu.domain
|
||||
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.Scrobbler
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus
|
||||
@@ -10,7 +11,8 @@ import javax.inject.Inject
|
||||
class KitsuScrobbler @Inject constructor(
|
||||
private val repository: KitsuRepository,
|
||||
db: MangaDatabase,
|
||||
) : Scrobbler(db, ScrobblerService.KITSU, repository) {
|
||||
mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) : Scrobbler(db, ScrobblerService.KITSU, repository, mangaRepositoryFactory) {
|
||||
|
||||
init {
|
||||
statuses[ScrobblingStatus.PLANNED] = "planned"
|
||||
|
||||
@@ -10,7 +10,6 @@ import okhttp3.Request
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.util.await
|
||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSONNotNull
|
||||
@@ -132,9 +131,9 @@ class MALRepository @Inject constructor(
|
||||
saveRate(response, mangaId, scrobblerMangaId)
|
||||
}
|
||||
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: MangaChapter) {
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: Int) {
|
||||
val body = FormBody.Builder()
|
||||
.add("num_chapters_read", chapter.number.toString())
|
||||
.add("num_chapters_read", chapter.toString())
|
||||
val url = BASE_API_URL.toHttpUrl().newBuilder()
|
||||
.addPathSegment("manga")
|
||||
.addPathSegment(rateId.toString())
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.scrobbling.mal.domain
|
||||
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.Scrobbler
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus
|
||||
@@ -14,7 +15,8 @@ private const val RATING_MAX = 10f
|
||||
class MALScrobbler @Inject constructor(
|
||||
private val repository: MALRepository,
|
||||
db: MangaDatabase,
|
||||
) : Scrobbler(db, ScrobblerService.MAL, repository) {
|
||||
mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) : Scrobbler(db, ScrobblerService.MAL, repository, mangaRepositoryFactory) {
|
||||
|
||||
init {
|
||||
statuses[ScrobblingStatus.PLANNED] = "plan_to_read"
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.util.ext.toRequestBody
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.util.await
|
||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
||||
@@ -130,12 +129,12 @@ class ShikimoriRepository @Inject constructor(
|
||||
saveRate(response, mangaId)
|
||||
}
|
||||
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: MangaChapter) {
|
||||
override suspend fun updateRate(rateId: Int, mangaId: Long, chapter: Int) {
|
||||
val payload = JSONObject()
|
||||
payload.put(
|
||||
"user_rate",
|
||||
JSONObject().apply {
|
||||
put("chapters", chapter.number)
|
||||
put("chapters", chapter)
|
||||
},
|
||||
)
|
||||
val url = BASE_URL.toHttpUrl().newBuilder()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.scrobbling.shikimori.domain
|
||||
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.Scrobbler
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
|
||||
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus
|
||||
@@ -14,7 +15,8 @@ private const val RATING_MAX = 10f
|
||||
class ShikimoriScrobbler @Inject constructor(
|
||||
private val repository: ShikimoriRepository,
|
||||
db: MangaDatabase,
|
||||
) : Scrobbler(db, ScrobblerService.SHIKIMORI, repository) {
|
||||
mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) : Scrobbler(db, ScrobblerService.SHIKIMORI, repository, mangaRepositoryFactory) {
|
||||
|
||||
init {
|
||||
statuses[ScrobblingStatus.PLANNED] = "planned"
|
||||
|
||||
Reference in New Issue
Block a user