Update types of legacy tracker model to match to domain one (#245)

* `score` to Double

* `tracker_id` to Long

* `last_chapter_read` to Double

* `total_chapters` to Long

* `status` to Long
This commit is contained in:
AntsyLich 2024-01-27 23:17:09 +06:00 committed by GitHub
parent 65bfa083f2
commit 05efc4ebeb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 249 additions and 244 deletions

View file

@ -19,10 +19,10 @@ fun Track.toDbTrack(): DbTrack = DbTrack.create(trackerId).also {
it.remote_id = remoteId it.remote_id = remoteId
it.library_id = libraryId it.library_id = libraryId
it.title = title it.title = title
it.last_chapter_read = lastChapterRead.toFloat() it.last_chapter_read = lastChapterRead
it.total_chapters = totalChapters.toInt() it.total_chapters = totalChapters
it.status = status.toInt() it.status = status
it.score = score.toFloat() it.score = score
it.tracking_url = remoteUrl it.tracking_url = remoteUrl
it.started_reading_date = startDate it.started_reading_date = startDate
it.finished_reading_date = finishDate it.finished_reading_date = finishDate
@ -33,16 +33,14 @@ fun DbTrack.toDomainTrack(idRequired: Boolean = true): Track? {
return Track( return Track(
id = trackId, id = trackId,
mangaId = manga_id, mangaId = manga_id,
trackerId = tracker_id.toLong(), trackerId = tracker_id,
remoteId = remote_id, remoteId = remote_id,
libraryId = library_id, libraryId = library_id,
title = title, title = title,
lastChapterRead = last_chapter_read.toDouble(), lastChapterRead = last_chapter_read,
totalChapters = total_chapters.toLong(), totalChapters = total_chapters,
status = status.toLong(), status = status,
// Jank workaround due to precision issues while converting score = score,
// See https://github.com/tachiyomiorg/tachiyomi/issues/10343
score = score.toString().toDouble(),
remoteUrl = tracking_url, remoteUrl = tracking_url,
startDate = started_reading_date, startDate = started_reading_date,
finishDate = finished_reading_date, finishDate = finished_reading_date,

View file

@ -88,7 +88,7 @@ fun TrackInfoDialogHome(
TrackInfoItem( TrackInfoItem(
title = item.track.title, title = item.track.title,
tracker = item.tracker, tracker = item.tracker,
status = item.tracker.getStatus(item.track.status.toInt()), status = item.tracker.getStatus(item.track.status),
onStatusClick = { onStatusClick(item) }, onStatusClick = { onStatusClick(item) },
chapters = "${item.track.lastChapterRead.toInt()}".let { chapters = "${item.track.lastChapterRead.toInt()}".let {
val totalChapters = item.track.totalChapters val totalChapters = item.track.totalChapters

View file

@ -48,9 +48,9 @@ import tachiyomi.presentation.core.util.isScrolledToStart
@Composable @Composable
fun TrackStatusSelector( fun TrackStatusSelector(
selection: Int, selection: Long,
onSelectionChange: (Int) -> Unit, onSelectionChange: (Long) -> Unit,
selections: Map<Int, StringResource?>, selections: Map<Long, StringResource?>,
onConfirm: () -> Unit, onConfirm: () -> Unit,
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) { ) {
@ -236,12 +236,12 @@ private fun TrackStatusSelectorPreviews() {
onSelectionChange = {}, onSelectionChange = {},
selections = persistentMapOf( selections = persistentMapOf(
// Anilist values // Anilist values
1 to MR.strings.reading, 1L to MR.strings.reading,
2 to MR.strings.plan_to_read, 2L to MR.strings.plan_to_read,
3 to MR.strings.completed, 3L to MR.strings.completed,
4 to MR.strings.on_hold, 4L to MR.strings.on_hold,
5 to MR.strings.dropped, 5L to MR.strings.dropped,
6 to MR.strings.repeating, 6L to MR.strings.repeating,
), ),
onConfirm = {}, onConfirm = {},
onDismissRequest = {}, onDismissRequest = {},

View file

@ -301,7 +301,7 @@ private fun SearchResultItem(
text = status, text = status,
) )
} }
if (trackSearch.score != -1f) { if (trackSearch.score != -1.0) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(MR.strings.score), title = stringResource(MR.strings.score),
text = trackSearch.score.toString(), text = trackSearch.score.toString(),

View file

@ -62,14 +62,14 @@ internal class TrackerSearchPreviewProvider : PreviewParameterProvider<@Composab
private fun randTrackSearch() = TrackSearch().let { private fun randTrackSearch() = TrackSearch().let {
it.id = Random.nextLong() it.id = Random.nextLong()
it.manga_id = Random.nextLong() it.manga_id = Random.nextLong()
it.tracker_id = Random.nextInt() it.tracker_id = Random.nextLong()
it.remote_id = Random.nextLong() it.remote_id = Random.nextLong()
it.library_id = Random.nextLong() it.library_id = Random.nextLong()
it.title = lorem((1..10).random()).joinToString() it.title = lorem((1..10).random()).joinToString()
it.last_chapter_read = (0..100).random().toFloat() it.last_chapter_read = (0..100).random().toDouble()
it.total_chapters = (100..1000).random() it.total_chapters = (100L..1000L).random()
it.score = (0..10).random().toFloat() it.score = (0..10).random().toDouble()
it.status = Random.nextInt() it.status = Random.nextLong()
it.started_reading_date = 0L it.started_reading_date = 0L
it.finished_reading_date = 0L it.finished_reading_date = 0L
it.tracking_url = "https://example.com/tracker-example" it.tracking_url = "https://example.com/tracker-example"

View file

@ -8,7 +8,7 @@ interface Track : Serializable {
var manga_id: Long var manga_id: Long
var tracker_id: Int var tracker_id: Long
var remote_id: Long var remote_id: Long
@ -16,13 +16,13 @@ interface Track : Serializable {
var title: String var title: String
var last_chapter_read: Float var last_chapter_read: Double
var total_chapters: Int var total_chapters: Long
var score: Float var score: Double
var status: Int var status: Long
var started_reading_date: Long var started_reading_date: Long
@ -40,7 +40,7 @@ interface Track : Serializable {
companion object { companion object {
fun create(serviceId: Long): Track = TrackImpl().apply { fun create(serviceId: Long): Track = TrackImpl().apply {
tracker_id = serviceId.toInt() tracker_id = serviceId
} }
} }
} }

View file

@ -6,7 +6,7 @@ class TrackImpl : Track {
override var manga_id: Long = 0 override var manga_id: Long = 0
override var tracker_id: Int = 0 override var tracker_id: Long = 0
override var remote_id: Long = 0 override var remote_id: Long = 0
@ -14,13 +14,13 @@ class TrackImpl : Track {
override lateinit var title: String override lateinit var title: String
override var last_chapter_read: Float = 0F override var last_chapter_read: Double = 0.0
override var total_chapters: Int = 0 override var total_chapters: Long = 0
override var score: Float = 0f override var score: Double = 0.0
override var status: Int = 0 override var status: Long = 0
override var started_reading_date: Long = 0 override var started_reading_date: Long = 0

View file

@ -40,8 +40,8 @@ abstract class BaseTracker(
return track.score return track.score
} }
override fun indexToScore(index: Int): Float { override fun indexToScore(index: Int): Double {
return index.toFloat() return index.toDouble()
} }
@CallSuper @CallSuper
@ -70,24 +70,24 @@ abstract class BaseTracker(
} }
} }
override suspend fun setRemoteStatus(track: Track, status: Int) { override suspend fun setRemoteStatus(track: Track, status: Long) {
track.status = status track.status = status
if (track.status == getCompletionStatus() && track.total_chapters != 0) { if (track.status == getCompletionStatus() && track.total_chapters != 0L) {
track.last_chapter_read = track.total_chapters.toFloat() track.last_chapter_read = track.total_chapters.toDouble()
} }
updateRemote(track) updateRemote(track)
} }
override suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int) { override suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int) {
if ( if (
track.last_chapter_read == 0f && track.last_chapter_read == 0.0 &&
track.last_chapter_read < chapterNumber && track.last_chapter_read < chapterNumber &&
track.status != getRereadingStatus() track.status != getRereadingStatus()
) { ) {
track.status = getReadingStatus() track.status = getReadingStatus()
} }
track.last_chapter_read = chapterNumber.toFloat() track.last_chapter_read = chapterNumber.toDouble()
if (track.total_chapters != 0 && track.last_chapter_read.toInt() == track.total_chapters) { if (track.total_chapters != 0L && track.last_chapter_read.toLong() == track.total_chapters) {
track.status = getCompletionStatus() track.status = getCompletionStatus()
track.finished_reading_date = System.currentTimeMillis() track.finished_reading_date = System.currentTimeMillis()
} }

View file

@ -27,22 +27,22 @@ interface Tracker {
@DrawableRes @DrawableRes
fun getLogo(): Int fun getLogo(): Int
fun getStatusList(): List<Int> fun getStatusList(): List<Long>
fun getStatus(status: Int): StringResource? fun getStatus(status: Long): StringResource?
fun getReadingStatus(): Int fun getReadingStatus(): Long
fun getRereadingStatus(): Int fun getRereadingStatus(): Long
fun getCompletionStatus(): Int fun getCompletionStatus(): Long
fun getScoreList(): ImmutableList<String> fun getScoreList(): ImmutableList<String>
// TODO: Store all scores as 10 point in the future maybe? // TODO: Store all scores as 10 point in the future maybe?
fun get10PointScore(track: DomainTrack): Double fun get10PointScore(track: DomainTrack): Double
fun indexToScore(index: Int): Float fun indexToScore(index: Int): Double
fun displayScore(track: DomainTrack): String fun displayScore(track: DomainTrack): String
@ -70,7 +70,7 @@ interface Tracker {
// TODO: move this to an interactor, and update all trackers based on common data // TODO: move this to an interactor, and update all trackers based on common data
suspend fun register(item: Track, mangaId: Long) suspend fun register(item: Track, mangaId: Long)
suspend fun setRemoteStatus(track: Track, status: Int) suspend fun setRemoteStatus(track: Track, status: Long)
suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int) suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int)

View file

@ -20,12 +20,12 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker { class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
companion object { companion object {
const val READING = 1 const val READING = 1L
const val COMPLETED = 2 const val COMPLETED = 2L
const val ON_HOLD = 3 const val ON_HOLD = 3L
const val DROPPED = 4 const val DROPPED = 4L
const val PLAN_TO_READ = 5 const val PLAN_TO_READ = 5L
const val REREADING = 6 const val REREADING = 6L
const val POINT_100 = "POINT_100" const val POINT_100 = "POINT_100"
const val POINT_10 = "POINT_10" const val POINT_10 = "POINT_10"
@ -58,11 +58,11 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
override fun getLogoColor() = Color.rgb(18, 25, 35) override fun getLogoColor() = Color.rgb(18, 25, 35)
override fun getStatusList(): List<Int> { override fun getStatusList(): List<Long> {
return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ, REREADING) return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ, REREADING)
} }
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
READING -> MR.strings.reading READING -> MR.strings.reading
PLAN_TO_READ -> MR.strings.plan_to_read PLAN_TO_READ -> MR.strings.plan_to_read
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
@ -72,11 +72,11 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = REREADING override fun getRereadingStatus(): Long = REREADING
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override fun getScoreList(): ImmutableList<String> { override fun getScoreList(): ImmutableList<String> {
return when (scorePreference.get()) { return when (scorePreference.get()) {
@ -99,24 +99,24 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
return track.score / 10.0 return track.score / 10.0
} }
override fun indexToScore(index: Int): Float { override fun indexToScore(index: Int): Double {
return when (scorePreference.get()) { return when (scorePreference.get()) {
// 10 point // 10 point
POINT_10 -> index * 10f POINT_10 -> index * 10.0
// 100 point // 100 point
POINT_100 -> index.toFloat() POINT_100 -> index.toDouble()
// 5 stars // 5 stars
POINT_5 -> when (index) { POINT_5 -> when (index) {
0 -> 0f 0 -> 0.0
else -> index * 20f - 10f else -> index * 20.0 - 10.0
} }
// Smiley // Smiley
POINT_3 -> when (index) { POINT_3 -> when (index) {
0 -> 0f 0 -> 0.0
else -> index * 25f + 10f else -> index * 25.0 + 10.0
} }
// 10 point decimal // 10 point decimal
POINT_10_DECIMAL -> index.toFloat() POINT_10_DECIMAL -> index.toDouble()
else -> throw Exception("Unknown score type") else -> throw Exception("Unknown score type")
} }
} }
@ -153,12 +153,12 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
track.finished_reading_date = System.currentTimeMillis() track.finished_reading_date = System.currentTimeMillis()
} else if (track.status != REREADING) { } else if (track.status != REREADING) {
track.status = READING track.status = READING
if (track.last_chapter_read == 1F) { if (track.last_chapter_read == 1.0) {
track.started_reading_date = System.currentTimeMillis() track.started_reading_date = System.currentTimeMillis()
} }
} }
@ -192,7 +192,7 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
} else { } else {
// Set default fields if it's not found in the list // Set default fields if it's not found in the list
track.status = if (hasReadChapters) READING else PLAN_TO_READ track.status = if (hasReadChapters) READING else PLAN_TO_READ
track.score = 0F track.score = 0.0
add(track) add(track)
} }
} }

View file

@ -20,6 +20,7 @@ import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long import kotlinx.serialization.json.long
import kotlinx.serialization.json.longOrNull
import kotlinx.serialization.json.put import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonObject import kotlinx.serialization.json.putJsonObject
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -312,7 +313,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
struct["format"]!!.jsonPrimitive.content.replace("_", "-"), struct["format"]!!.jsonPrimitive.content.replace("_", "-"),
struct["status"]!!.jsonPrimitive.contentOrNull ?: "", struct["status"]!!.jsonPrimitive.contentOrNull ?: "",
parseDate(struct, "startDate"), parseDate(struct, "startDate"),
struct["chapters"]!!.jsonPrimitive.intOrNull ?: 0, struct["chapters"]!!.jsonPrimitive.longOrNull ?: 0,
struct["averageScore"]?.jsonPrimitive?.intOrNull ?: -1, struct["averageScore"]?.jsonPrimitive?.intOrNull ?: -1,
) )
} }

View file

@ -19,7 +19,7 @@ data class ALManga(
val format: String, val format: String,
val publishing_status: String, val publishing_status: String,
val start_date_fuzzy: Long, val start_date_fuzzy: Long,
val total_chapters: Int, val total_chapters: Long,
val average_score: Int, val average_score: Int,
) { ) {
@ -29,7 +29,7 @@ data class ALManga(
total_chapters = this@ALManga.total_chapters total_chapters = this@ALManga.total_chapters
cover_url = image_url_lge cover_url = image_url_lge
summary = description?.htmlDecode() ?: "" summary = description?.htmlDecode() ?: ""
score = average_score.toFloat() score = average_score.toDouble()
tracking_url = AnilistApi.mangaUrl(remote_id) tracking_url = AnilistApi.mangaUrl(remote_id)
publishing_status = this@ALManga.publishing_status publishing_status = this@ALManga.publishing_status
publishing_type = format publishing_type = format
@ -58,10 +58,10 @@ data class ALUserManga(
remote_id = manga.remote_id remote_id = manga.remote_id
title = manga.title_user_pref title = manga.title_user_pref
status = toTrackStatus() status = toTrackStatus()
score = score_raw.toFloat() score = score_raw.toDouble()
started_reading_date = start_date_fuzzy started_reading_date = start_date_fuzzy
finished_reading_date = completed_date_fuzzy finished_reading_date = completed_date_fuzzy
last_chapter_read = chapters_read.toFloat() last_chapter_read = chapters_read.toDouble()
library_id = this@ALUserManga.library_id library_id = this@ALUserManga.library_id
total_chapters = manga.total_chapters total_chapters = manga.total_chapters
} }

View file

@ -35,7 +35,7 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
} else { } else {
track.status = READING track.status = READING
@ -64,7 +64,7 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
} else { } else {
// Set default fields if it's not found in the list // Set default fields if it's not found in the list
track.status = if (hasReadChapters) READING else PLAN_TO_READ track.status = if (hasReadChapters) READING else PLAN_TO_READ
track.score = 0F track.score = 0.0
add(track) add(track)
update(track) update(track)
} }
@ -87,11 +87,11 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
override fun getLogoColor() = Color.rgb(240, 145, 153) override fun getLogoColor() = Color.rgb(240, 145, 153)
override fun getStatusList(): List<Int> { override fun getStatusList(): List<Long> {
return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ) return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ)
} }
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
READING -> MR.strings.reading READING -> MR.strings.reading
PLAN_TO_READ -> MR.strings.plan_to_read PLAN_TO_READ -> MR.strings.plan_to_read
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
@ -100,11 +100,11 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = -1 override fun getRereadingStatus(): Long = -1
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override suspend fun login(username: String, password: String) = login(password) override suspend fun login(username: String, password: String) = login(password)
@ -137,11 +137,11 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
} }
companion object { companion object {
const val READING = 3 const val READING = 3L
const val COMPLETED = 2 const val COMPLETED = 2L
const val ON_HOLD = 4 const val ON_HOLD = 4L
const val DROPPED = 5 const val DROPPED = 5L
const val PLAN_TO_READ = 1 const val PLAN_TO_READ = 1L
private val SCORE_LIST = IntRange(0, 10) private val SCORE_LIST = IntRange(0, 10)
.map(Int::toString) .map(Int::toString)

View file

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.network.parseAs
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.doubleOrNull
import kotlinx.serialization.json.floatOrNull import kotlinx.serialization.json.floatOrNull
import kotlinx.serialization.json.int import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
@ -105,11 +106,11 @@ class BangumiApi(
"" ""
} }
val totalChapters = if (obj["eps_count"] != null) { val totalChapters = if (obj["eps_count"] != null) {
obj["eps_count"]!!.jsonPrimitive.int obj["eps_count"]!!.jsonPrimitive.long
} else { } else {
0 0
} }
val rating = obj["rating"]?.jsonObject?.get("score")?.jsonPrimitive?.floatOrNull ?: -1f val rating = obj["rating"]?.jsonObject?.get("score")?.jsonPrimitive?.doubleOrNull ?: -1.0
return TrackSearch.create(trackId).apply { return TrackSearch.create(trackId).apply {
remote_id = obj["id"]!!.jsonPrimitive.long remote_id = obj["id"]!!.jsonPrimitive.long
title = obj["name_cn"]!!.jsonPrimitive.content title = obj["name_cn"]!!.jsonPrimitive.content
@ -152,7 +153,7 @@ class BangumiApi(
} else { } else {
json.decodeFromString<Collection>(responseBody).let { json.decodeFromString<Collection>(responseBody).let {
track.status = it.status?.id!! track.status = it.status?.id!!
track.last_chapter_read = it.ep_status!!.toFloat() track.last_chapter_read = it.ep_status!!.toDouble()
track.score = it.rating!! track.score = it.rating!!
track track
} }

View file

@ -16,7 +16,7 @@ data class Collection(
val comment: String? = "", val comment: String? = "",
val ep_status: Int? = 0, val ep_status: Int? = 0,
val lasttouch: Int? = 0, val lasttouch: Int? = 0,
val rating: Float? = 0f, val rating: Double? = 0.0,
val status: Status? = Status(), val status: Status? = Status(),
val tag: List<String?>? = emptyList(), val tag: List<String?>? = emptyList(),
val user: User? = User(), val user: User? = User(),
@ -25,7 +25,7 @@ data class Collection(
@Serializable @Serializable
data class Status( data class Status(
val id: Int? = 0, val id: Long? = 0,
val name: String? = "", val name: String? = "",
val type: String? = "", val type: String? = "",
) )

View file

@ -22,9 +22,9 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker { class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
companion object { companion object {
const val UNREAD = 1 const val UNREAD = 1L
const val READING = 2 const val READING = 2L
const val COMPLETED = 3 const val COMPLETED = 3L
} }
var authentications: OAuth? = null var authentications: OAuth? = null
@ -38,20 +38,20 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
override fun getLogoColor() = Color.rgb(74, 198, 148) override fun getLogoColor() = Color.rgb(74, 198, 148)
override fun getStatusList() = listOf(UNREAD, READING, COMPLETED) override fun getStatusList(): List<Long> = listOf(UNREAD, READING, COMPLETED)
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
UNREAD -> MR.strings.unread UNREAD -> MR.strings.unread
READING -> MR.strings.reading READING -> MR.strings.reading
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = -1 override fun getRereadingStatus(): Long = -1
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override fun getScoreList(): ImmutableList<String> = persistentListOf() override fun getScoreList(): ImmutableList<String> = persistentListOf()
@ -60,7 +60,7 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
} else { } else {
track.status = READING track.status = READING

View file

@ -93,7 +93,7 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
* Ignores volumes. * Ignores volumes.
* Volumes consisting of 1 file treated as chapter * Volumes consisting of 1 file treated as chapter
*/ */
private fun getTotalChapters(url: String): Int { private fun getTotalChapters(url: String): Long {
val requestUrl = getApiVolumesUrl(url) val requestUrl = getApiVolumesUrl(url)
try { try {
val listVolumeDto = with(json) { val listVolumeDto = with(json) {
@ -101,13 +101,13 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
.execute() .execute()
.parseAs<List<VolumeDto>>() .parseAs<List<VolumeDto>>()
} }
var volumeNumber = 0 var volumeNumber = 0L
var maxChapterNumber = 0 var maxChapterNumber = 0L
for (volume in listVolumeDto) { for (volume in listVolumeDto) {
if (volume.chapters.maxOf { it.number!!.toFloat() } == 0f) { if (volume.chapters.maxOf { it.number!!.toFloat() } == 0f) {
volumeNumber++ volumeNumber++
} else if (maxChapterNumber < volume.chapters.maxOf { it.number!!.toFloat() }) { } else if (maxChapterNumber < volume.chapters.maxOf { it.number!!.toFloat() }) {
maxChapterNumber = volume.chapters.maxOf { it.number!!.toFloat().toInt() } maxChapterNumber = volume.chapters.maxOf { it.number!!.toFloat().toLong() }
} }
} }
@ -118,17 +118,17 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
} }
} }
private fun getLatestChapterRead(url: String): Float { private fun getLatestChapterRead(url: String): Double {
val seriesId = getIdFromUrl(url) val seriesId = getIdFromUrl(url)
val requestUrl = "${getApiFromUrl(url)}/Tachiyomi/latest-chapter?seriesId=$seriesId" val requestUrl = "${getApiFromUrl(url)}/Tachiyomi/latest-chapter?seriesId=$seriesId"
try { try {
with(json) { with(json) {
authClient.newCall(GET(requestUrl)).execute().use { authClient.newCall(GET(requestUrl)).execute().use {
if (it.code == 200) { if (it.code == 200) {
return it.parseAs<ChapterDto>().number!!.replace(",", ".").toFloat() return it.parseAs<ChapterDto>().number!!.replace(",", ".").toDouble()
} }
if (it.code == 204) { if (it.code == 204) {
return 0F return 0.0
} }
} }
} }
@ -139,7 +139,7 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
) { "Exception getting latest chapter read. Could not get itemRequest: $requestUrl" } ) { "Exception getting latest chapter read. Could not get itemRequest: $requestUrl" }
throw e throw e
} }
return 0F return 0.0
} }
suspend fun getTrackSearch(url: String): TrackSearch = withIOContext { suspend fun getTrackSearch(url: String): TrackSearch = withIOContext {

View file

@ -19,11 +19,11 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker { class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
companion object { companion object {
const val READING = 1 const val READING = 1L
const val COMPLETED = 2 const val COMPLETED = 2L
const val ON_HOLD = 3 const val ON_HOLD = 3L
const val DROPPED = 4 const val DROPPED = 4L
const val PLAN_TO_READ = 5 const val PLAN_TO_READ = 5L
} }
override val supportsReadingDates: Boolean = true override val supportsReadingDates: Boolean = true
@ -38,11 +38,11 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
override fun getLogoColor() = Color.rgb(51, 37, 50) override fun getLogoColor() = Color.rgb(51, 37, 50)
override fun getStatusList(): List<Int> { override fun getStatusList(): List<Long> {
return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ) return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ)
} }
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
READING -> MR.strings.reading READING -> MR.strings.reading
PLAN_TO_READ -> MR.strings.plan_to_read PLAN_TO_READ -> MR.strings.plan_to_read
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
@ -51,19 +51,19 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = -1 override fun getRereadingStatus(): Long = -1
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override fun getScoreList(): ImmutableList<String> { override fun getScoreList(): ImmutableList<String> {
val df = DecimalFormat("0.#") val df = DecimalFormat("0.#")
return (listOf("0") + IntRange(2, 20).map { df.format(it / 2f) }).toImmutableList() return (listOf("0") + IntRange(2, 20).map { df.format(it / 2f) }).toImmutableList()
} }
override fun indexToScore(index: Int): Float { override fun indexToScore(index: Int): Double {
return if (index > 0) (index + 1) / 2f else 0f return if (index > 0) (index + 1) / 2.0 else 0.0
} }
override fun displayScore(track: DomainTrack): String { override fun displayScore(track: DomainTrack): String {
@ -78,12 +78,12 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
track.finished_reading_date = System.currentTimeMillis() track.finished_reading_date = System.currentTimeMillis()
} else { } else {
track.status = READING track.status = READING
if (track.last_chapter_read == 1F) { if (track.last_chapter_read == 1.0) {
track.started_reading_date = System.currentTimeMillis() track.started_reading_date = System.currentTimeMillis()
} }
} }
@ -110,7 +110,7 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
update(track) update(track)
} else { } else {
track.status = if (hasReadChapters) READING else PLAN_TO_READ track.status = if (hasReadChapters) READING else PLAN_TO_READ
track.score = 0F track.score = 0.0
add(track) add(track)
} }
} }

View file

@ -12,6 +12,7 @@ import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long import kotlinx.serialization.json.long
import kotlinx.serialization.json.longOrNull
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@ -19,7 +20,7 @@ import java.util.Locale
class KitsuSearchManga(obj: JsonObject) { class KitsuSearchManga(obj: JsonObject) {
val id = obj["id"]!!.jsonPrimitive.long val id = obj["id"]!!.jsonPrimitive.long
private val canonicalTitle = obj["canonicalTitle"]!!.jsonPrimitive.content private val canonicalTitle = obj["canonicalTitle"]!!.jsonPrimitive.content
private val chapterCount = obj["chapterCount"]?.jsonPrimitive?.intOrNull private val chapterCount = obj["chapterCount"]?.jsonPrimitive?.longOrNull
val subType = obj["subtype"]?.jsonPrimitive?.contentOrNull val subType = obj["subtype"]?.jsonPrimitive?.contentOrNull
val original = try { val original = try {
obj["posterImage"]?.jsonObject?.get("original")?.jsonPrimitive?.content obj["posterImage"]?.jsonObject?.get("original")?.jsonPrimitive?.content
@ -28,7 +29,7 @@ class KitsuSearchManga(obj: JsonObject) {
null null
} }
private val synopsis = obj["synopsis"]?.jsonPrimitive?.contentOrNull private val synopsis = obj["synopsis"]?.jsonPrimitive?.contentOrNull
private val rating = obj["averageRating"]?.jsonPrimitive?.contentOrNull?.toFloatOrNull() private val rating = obj["averageRating"]?.jsonPrimitive?.contentOrNull?.toDoubleOrNull()
private var startDate = obj["startDate"]?.jsonPrimitive?.contentOrNull?.let { private var startDate = obj["startDate"]?.jsonPrimitive?.contentOrNull?.let {
val outputDf = SimpleDateFormat("yyyy-MM-dd", Locale.US) val outputDf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
outputDf.format(Date(it.toLong() * 1000)) outputDf.format(Date(it.toLong() * 1000))
@ -43,7 +44,7 @@ class KitsuSearchManga(obj: JsonObject) {
cover_url = original ?: "" cover_url = original ?: ""
summary = synopsis ?: "" summary = synopsis ?: ""
tracking_url = KitsuApi.mangaUrl(remote_id) tracking_url = KitsuApi.mangaUrl(remote_id)
score = rating ?: -1f score = rating ?: -1.0
publishing_status = if (endDate == null) { publishing_status = if (endDate == null) {
"Publishing" "Publishing"
} else { } else {
@ -57,7 +58,7 @@ class KitsuSearchManga(obj: JsonObject) {
class KitsuLibManga(obj: JsonObject, manga: JsonObject) { class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
val id = manga["id"]!!.jsonPrimitive.int val id = manga["id"]!!.jsonPrimitive.int
private val canonicalTitle = manga["attributes"]!!.jsonObject["canonicalTitle"]!!.jsonPrimitive.content private val canonicalTitle = manga["attributes"]!!.jsonObject["canonicalTitle"]!!.jsonPrimitive.content
private val chapterCount = manga["attributes"]!!.jsonObject["chapterCount"]?.jsonPrimitive?.intOrNull private val chapterCount = manga["attributes"]!!.jsonObject["chapterCount"]?.jsonPrimitive?.longOrNull
val type = manga["attributes"]!!.jsonObject["mangaType"]?.jsonPrimitive?.contentOrNull.orEmpty() val type = manga["attributes"]!!.jsonObject["mangaType"]?.jsonPrimitive?.contentOrNull.orEmpty()
val original = manga["attributes"]!!.jsonObject["posterImage"]!!.jsonObject["original"]!!.jsonPrimitive.content val original = manga["attributes"]!!.jsonObject["posterImage"]!!.jsonObject["original"]!!.jsonPrimitive.content
private val synopsis = manga["attributes"]!!.jsonObject["synopsis"]!!.jsonPrimitive.content private val synopsis = manga["attributes"]!!.jsonObject["synopsis"]!!.jsonPrimitive.content
@ -82,8 +83,8 @@ class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
started_reading_date = KitsuDateHelper.parse(startedAt) started_reading_date = KitsuDateHelper.parse(startedAt)
finished_reading_date = KitsuDateHelper.parse(finishedAt) finished_reading_date = KitsuDateHelper.parse(finishedAt)
status = toTrackStatus() status = toTrackStatus()
score = ratingTwenty?.let { it.toInt() / 2f } ?: 0f score = ratingTwenty?.let { it.toInt() / 2.0 } ?: 0.0
last_chapter_read = progress.toFloat() last_chapter_read = progress.toDouble()
} }
private fun toTrackStatus() = when (status) { private fun toTrackStatus() = when (status) {

View file

@ -19,9 +19,9 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker { class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker {
companion object { companion object {
const val UNREAD = 1 const val UNREAD = 1L
const val READING = 2 const val READING = 2L
const val COMPLETED = 3 const val COMPLETED = 3L
} }
override val client: OkHttpClient = override val client: OkHttpClient =
@ -35,20 +35,20 @@ class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker {
override fun getLogoColor() = Color.rgb(51, 37, 50) override fun getLogoColor() = Color.rgb(51, 37, 50)
override fun getStatusList() = listOf(UNREAD, READING, COMPLETED) override fun getStatusList(): List<Long> = listOf(UNREAD, READING, COMPLETED)
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
UNREAD -> MR.strings.unread UNREAD -> MR.strings.unread
READING -> MR.strings.reading READING -> MR.strings.reading
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = -1 override fun getRereadingStatus(): Long = -1
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override fun getScoreList(): ImmutableList<String> = persistentListOf() override fun getScoreList(): ImmutableList<String> = persistentListOf()
@ -57,7 +57,7 @@ class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
} else { } else {
track.status = READING track.status = READING

View file

@ -67,7 +67,7 @@ class KomgaApi(
track.apply { track.apply {
cover_url = "$url/thumbnail" cover_url = "$url/thumbnail"
tracking_url = url tracking_url = url
total_chapters = progress.maxNumberSort.toInt() total_chapters = progress.maxNumberSort.toLong()
status = when (progress.booksCount) { status = when (progress.booksCount) {
progress.booksUnreadCount -> Komga.UNREAD progress.booksUnreadCount -> Komga.UNREAD
progress.booksReadCount -> Komga.COMPLETED progress.booksReadCount -> Komga.COMPLETED

View file

@ -65,7 +65,7 @@ data class ReadProgressUpdateDto(
@Serializable @Serializable
data class ReadProgressUpdateV2Dto( data class ReadProgressUpdateV2Dto(
val lastBookNumberSortRead: Float, val lastBookNumberSortRead: Double,
) )
@Serializable @Serializable
@ -91,7 +91,7 @@ data class ReadProgressDto(
booksReadCount, booksReadCount,
booksUnreadCount, booksUnreadCount,
booksInProgressCount, booksInProgressCount,
lastReadContinuousIndex.toFloat(), lastReadContinuousIndex.toDouble(),
booksCount.toFloat(), booksCount.toFloat(),
) )
} }
@ -102,6 +102,6 @@ data class ReadProgressV2Dto(
val booksReadCount: Int, val booksReadCount: Int,
val booksUnreadCount: Int, val booksUnreadCount: Int,
val booksInProgressCount: Int, val booksInProgressCount: Int,
val lastReadContinuousNumberSort: Float, val lastReadContinuousNumberSort: Double,
val maxNumberSort: Float, val maxNumberSort: Float,
) )

View file

@ -19,11 +19,11 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker { class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker {
companion object { companion object {
const val READING_LIST = 0 const val READING_LIST = 0L
const val WISH_LIST = 1 const val WISH_LIST = 1L
const val COMPLETE_LIST = 2 const val COMPLETE_LIST = 2L
const val UNFINISHED_LIST = 3 const val UNFINISHED_LIST = 3L
const val ON_HOLD_LIST = 4 const val ON_HOLD_LIST = 4L
private val SCORE_LIST = (0..10) private val SCORE_LIST = (0..10)
.flatMap { decimal -> .flatMap { decimal ->
@ -46,11 +46,11 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
override fun getLogoColor(): Int = Color.rgb(146, 160, 173) override fun getLogoColor(): Int = Color.rgb(146, 160, 173)
override fun getStatusList(): List<Int> { override fun getStatusList(): List<Long> {
return listOf(READING_LIST, COMPLETE_LIST, ON_HOLD_LIST, UNFINISHED_LIST, WISH_LIST) return listOf(READING_LIST, COMPLETE_LIST, ON_HOLD_LIST, UNFINISHED_LIST, WISH_LIST)
} }
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
READING_LIST -> MR.strings.reading_list READING_LIST -> MR.strings.reading_list
WISH_LIST -> MR.strings.wish_list WISH_LIST -> MR.strings.wish_list
COMPLETE_LIST -> MR.strings.complete_list COMPLETE_LIST -> MR.strings.complete_list
@ -59,15 +59,15 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING_LIST override fun getReadingStatus(): Long = READING_LIST
override fun getRereadingStatus(): Int = -1 override fun getRereadingStatus(): Long = -1
override fun getCompletionStatus(): Int = COMPLETE_LIST override fun getCompletionStatus(): Long = COMPLETE_LIST
override fun getScoreList(): ImmutableList<String> = SCORE_LIST override fun getScoreList(): ImmutableList<String> = SCORE_LIST
override fun indexToScore(index: Int): Float = if (index == 0) 0f else SCORE_LIST[index].toFloat() override fun indexToScore(index: Int): Double = if (index == 0) 0.0 else SCORE_LIST[index].toDouble()
override fun displayScore(track: DomainTrack): String = track.score.toString() override fun displayScore(track: DomainTrack): String = track.score.toString()
@ -88,7 +88,7 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
val (series, rating) = api.getSeriesListItem(track) val (series, rating) = api.getSeriesListItem(track)
track.copyFrom(series, rating) track.copyFrom(series, rating)
} catch (e: Exception) { } catch (e: Exception) {
track.score = 0f track.score = 0.0
api.addSeriesToList(track, hasReadChapters) api.addSeriesToList(track, hasReadChapters)
track track
} }
@ -108,7 +108,7 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
private fun Track.copyFrom(item: ListItem, rating: Rating?): Track = apply { private fun Track.copyFrom(item: ListItem, rating: Rating?): Track = apply {
item.copyTo(this) item.copyTo(this)
score = rating?.rating ?: 0f score = rating?.rating ?: 0.0
} }
override suspend fun login(username: String, password: String) { override suspend fun login(username: String, password: String) {

View file

@ -79,7 +79,7 @@ class MangaUpdatesApi(
.let { .let {
if (it.code == 200) { if (it.code == 200) {
track.status = status track.status = status
track.last_chapter_read = 1f track.last_chapter_read = 1.0
} }
} }
} }
@ -133,7 +133,8 @@ class MangaUpdatesApi(
} }
private suspend fun updateSeriesRating(track: Track) { private suspend fun updateSeriesRating(track: Track) {
if (track.score != 0f) { if (track.score < 0.0) return
if (track.score != 0.0) {
val body = buildJsonObject { val body = buildJsonObject {
put("rating", track.score) put("rating", track.score)
} }

View file

@ -9,7 +9,7 @@ import kotlinx.serialization.Serializable
data class ListItem( data class ListItem(
val series: Series? = null, val series: Series? = null,
@SerialName("list_id") @SerialName("list_id")
val listId: Int? = null, val listId: Long? = null,
val status: Status? = null, val status: Status? = null,
val priority: Int? = null, val priority: Int? = null,
) )
@ -17,6 +17,6 @@ data class ListItem(
fun ListItem.copyTo(track: Track): Track { fun ListItem.copyTo(track: Track): Track {
return track.apply { return track.apply {
this.status = listId ?: READING_LIST this.status = listId ?: READING_LIST
this.last_chapter_read = this@copyTo.status?.chapter?.toFloat() ?: 0f this.last_chapter_read = this@copyTo.status?.chapter?.toDouble() ?: 0.0
} }
} }

View file

@ -5,11 +5,11 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class Rating( data class Rating(
val rating: Float? = null, val rating: Double? = null,
) )
fun Rating.copyTo(track: Track): Track { fun Rating.copyTo(track: Track): Track {
return track.apply { return track.apply {
this.score = rating ?: 0f this.score = rating ?: 0.0
} }
} }

View file

@ -8,7 +8,7 @@ class TrackSearch : Track {
override var manga_id: Long = 0 override var manga_id: Long = 0
override var tracker_id: Int = 0 override var tracker_id: Long = 0
override var remote_id: Long = 0 override var remote_id: Long = 0
@ -16,13 +16,13 @@ class TrackSearch : Track {
override lateinit var title: String override lateinit var title: String
override var last_chapter_read: Float = 0F override var last_chapter_read: Double = 0.0
override var total_chapters: Int = 0 override var total_chapters: Long = 0
override var score: Float = -1f override var score: Double = -1.0
override var status: Int = 0 override var status: Long = 0
override var started_reading_date: Long = 0 override var started_reading_date: Long = 0
@ -55,14 +55,14 @@ class TrackSearch : Track {
override fun hashCode(): Int { override fun hashCode(): Int {
var result = manga_id.hashCode() var result = manga_id.hashCode()
result = 31 * result + tracker_id result = 31 * result + tracker_id.hashCode()
result = 31 * result + remote_id.hashCode() result = 31 * result + remote_id.hashCode()
return result return result
} }
companion object { companion object {
fun create(serviceId: Long): TrackSearch = TrackSearch().apply { fun create(serviceId: Long): TrackSearch = TrackSearch().apply {
tracker_id = serviceId.toInt() tracker_id = serviceId
} }
} }
} }

View file

@ -18,12 +18,12 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker { class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
companion object { companion object {
const val READING = 1 const val READING = 1L
const val COMPLETED = 2 const val COMPLETED = 2L
const val ON_HOLD = 3 const val ON_HOLD = 3L
const val DROPPED = 4 const val DROPPED = 4L
const val PLAN_TO_READ = 6 const val PLAN_TO_READ = 6L
const val REREADING = 7 const val REREADING = 7L
private const val SEARCH_ID_PREFIX = "id:" private const val SEARCH_ID_PREFIX = "id:"
private const val SEARCH_LIST_PREFIX = "my:" private const val SEARCH_LIST_PREFIX = "my:"
@ -44,11 +44,11 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
override fun getLogoColor() = Color.rgb(46, 81, 162) override fun getLogoColor() = Color.rgb(46, 81, 162)
override fun getStatusList(): List<Int> { override fun getStatusList(): List<Long> {
return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ, REREADING) return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ, REREADING)
} }
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
READING -> MR.strings.reading READING -> MR.strings.reading
PLAN_TO_READ -> MR.strings.plan_to_read PLAN_TO_READ -> MR.strings.plan_to_read
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
@ -58,11 +58,11 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = REREADING override fun getRereadingStatus(): Long = REREADING
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override fun getScoreList(): ImmutableList<String> = SCORE_LIST override fun getScoreList(): ImmutableList<String> = SCORE_LIST
@ -77,12 +77,12 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
track.finished_reading_date = System.currentTimeMillis() track.finished_reading_date = System.currentTimeMillis()
} else if (track.status != REREADING) { } else if (track.status != REREADING) {
track.status = READING track.status = READING
if (track.last_chapter_read == 1F) { if (track.last_chapter_read == 1.0) {
track.started_reading_date = System.currentTimeMillis() track.started_reading_date = System.currentTimeMillis()
} }
} }
@ -111,7 +111,7 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
} else { } else {
// Set default fields if it's not found in the list // Set default fields if it's not found in the list
track.status = if (hasReadChapters) READING else PLAN_TO_READ track.status = if (hasReadChapters) READING else PLAN_TO_READ
track.score = 0F track.score = 0.0
add(track) add(track)
} }
} }

View file

@ -16,6 +16,8 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.boolean import kotlinx.serialization.json.boolean
import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.double
import kotlinx.serialization.json.doubleOrNull
import kotlinx.serialization.json.float import kotlinx.serialization.json.float
import kotlinx.serialization.json.floatOrNull import kotlinx.serialization.json.floatOrNull
import kotlinx.serialization.json.int import kotlinx.serialization.json.int
@ -119,8 +121,8 @@ class MyAnimeListApi(
remote_id = obj["id"]!!.jsonPrimitive.long remote_id = obj["id"]!!.jsonPrimitive.long
title = obj["title"]!!.jsonPrimitive.content title = obj["title"]!!.jsonPrimitive.content
summary = obj["synopsis"]?.jsonPrimitive?.content ?: "" summary = obj["synopsis"]?.jsonPrimitive?.content ?: ""
total_chapters = obj["num_chapters"]!!.jsonPrimitive.int total_chapters = obj["num_chapters"]!!.jsonPrimitive.long
score = obj["mean"]?.jsonPrimitive?.floatOrNull ?: -1f score = obj["mean"]?.jsonPrimitive?.doubleOrNull ?: -1.0
cover_url = cover_url =
obj["main_picture"]?.jsonObject?.get("large")?.jsonPrimitive?.content obj["main_picture"]?.jsonObject?.get("large")?.jsonPrimitive?.content
?: "" ?: ""
@ -187,7 +189,7 @@ class MyAnimeListApi(
.awaitSuccess() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { obj -> .let { obj ->
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.long
obj.jsonObject["my_list_status"]?.jsonObject?.let { obj.jsonObject["my_list_status"]?.jsonObject?.let {
parseMangaItem(it, track) parseMangaItem(it, track)
} }
@ -249,8 +251,8 @@ class MyAnimeListApi(
return track.apply { return track.apply {
val isRereading = obj["is_rereading"]!!.jsonPrimitive.boolean val isRereading = obj["is_rereading"]!!.jsonPrimitive.boolean
status = if (isRereading) MyAnimeList.REREADING else getStatus(obj["status"]?.jsonPrimitive?.content) status = if (isRereading) MyAnimeList.REREADING else getStatus(obj["status"]?.jsonPrimitive?.content)
last_chapter_read = obj["num_chapters_read"]!!.jsonPrimitive.float last_chapter_read = obj["num_chapters_read"]!!.jsonPrimitive.double
score = obj["score"]!!.jsonPrimitive.int.toFloat() score = obj["score"]!!.jsonPrimitive.int.toDouble()
obj["start_date"]?.let { obj["start_date"]?.let {
started_reading_date = parseDate(it.jsonPrimitive.content) started_reading_date = parseDate(it.jsonPrimitive.content)
} }

View file

@ -18,12 +18,12 @@ import tachiyomi.domain.track.model.Track as DomainTrack
class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker { class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
companion object { companion object {
const val READING = 1 const val READING = 1L
const val COMPLETED = 2 const val COMPLETED = 2L
const val ON_HOLD = 3 const val ON_HOLD = 3L
const val DROPPED = 4 const val DROPPED = 4L
const val PLAN_TO_READ = 5 const val PLAN_TO_READ = 5L
const val REREADING = 6 const val REREADING = 6L
private val SCORE_LIST = IntRange(0, 10) private val SCORE_LIST = IntRange(0, 10)
.map(Int::toString) .map(Int::toString)
@ -49,7 +49,7 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
} else if (track.status != REREADING) { } else if (track.status != REREADING) {
track.status = READING track.status = READING
@ -79,7 +79,7 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
} else { } else {
// Set default fields if it's not found in the list // Set default fields if it's not found in the list
track.status = if (hasReadChapters) READING else PLAN_TO_READ track.status = if (hasReadChapters) READING else PLAN_TO_READ
track.score = 0F track.score = 0.0
add(track) add(track)
} }
} }
@ -101,11 +101,11 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
override fun getLogoColor() = Color.rgb(40, 40, 40) override fun getLogoColor() = Color.rgb(40, 40, 40)
override fun getStatusList(): List<Int> { override fun getStatusList(): List<Long> {
return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ, REREADING) return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLAN_TO_READ, REREADING)
} }
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
READING -> MR.strings.reading READING -> MR.strings.reading
PLAN_TO_READ -> MR.strings.plan_to_read PLAN_TO_READ -> MR.strings.plan_to_read
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
@ -115,11 +115,11 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = REREADING override fun getRereadingStatus(): Long = REREADING
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override suspend fun login(username: String, password: String) = login(password) override suspend fun login(username: String, password: String) = login(password)

View file

@ -15,6 +15,7 @@ import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.double
import kotlinx.serialization.json.float import kotlinx.serialization.json.float
import kotlinx.serialization.json.int import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
@ -102,10 +103,10 @@ class ShikimoriApi(
return TrackSearch.create(trackId).apply { return TrackSearch.create(trackId).apply {
remote_id = obj["id"]!!.jsonPrimitive.long remote_id = obj["id"]!!.jsonPrimitive.long
title = obj["name"]!!.jsonPrimitive.content title = obj["name"]!!.jsonPrimitive.content
total_chapters = obj["chapters"]!!.jsonPrimitive.int total_chapters = obj["chapters"]!!.jsonPrimitive.long
cover_url = baseUrl + obj["image"]!!.jsonObject["preview"]!!.jsonPrimitive.content cover_url = baseUrl + obj["image"]!!.jsonObject["preview"]!!.jsonPrimitive.content
summary = "" summary = ""
score = obj["score"]!!.jsonPrimitive.float score = obj["score"]!!.jsonPrimitive.double
tracking_url = baseUrl + obj["url"]!!.jsonPrimitive.content tracking_url = baseUrl + obj["url"]!!.jsonPrimitive.content
publishing_status = obj["status"]!!.jsonPrimitive.content publishing_status = obj["status"]!!.jsonPrimitive.content
publishing_type = obj["kind"]!!.jsonPrimitive.content publishing_type = obj["kind"]!!.jsonPrimitive.content
@ -117,10 +118,10 @@ class ShikimoriApi(
return Track.create(trackId).apply { return Track.create(trackId).apply {
title = mangas["name"]!!.jsonPrimitive.content title = mangas["name"]!!.jsonPrimitive.content
remote_id = obj["id"]!!.jsonPrimitive.long remote_id = obj["id"]!!.jsonPrimitive.long
total_chapters = mangas["chapters"]!!.jsonPrimitive.int total_chapters = mangas["chapters"]!!.jsonPrimitive.long
library_id = obj["id"]!!.jsonPrimitive.long library_id = obj["id"]!!.jsonPrimitive.long
last_chapter_read = obj["chapters"]!!.jsonPrimitive.float last_chapter_read = obj["chapters"]!!.jsonPrimitive.double
score = (obj["score"]!!.jsonPrimitive.int).toFloat() score = obj["score"]!!.jsonPrimitive.int.toDouble()
status = toTrackStatus(obj["status"]!!.jsonPrimitive.content) status = toTrackStatus(obj["status"]!!.jsonPrimitive.content)
tracking_url = baseUrl + mangas["url"]!!.jsonPrimitive.content tracking_url = baseUrl + mangas["url"]!!.jsonPrimitive.content
} }

View file

@ -23,25 +23,25 @@ class Suwayomi(id: Long) : BaseTracker(id, "Suwayomi"), EnhancedTracker {
override fun getLogoColor() = Color.rgb(255, 35, 35) // TODO override fun getLogoColor() = Color.rgb(255, 35, 35) // TODO
companion object { companion object {
const val UNREAD = 1 const val UNREAD = 1L
const val READING = 2 const val READING = 2L
const val COMPLETED = 3 const val COMPLETED = 3L
} }
override fun getStatusList() = listOf(UNREAD, READING, COMPLETED) override fun getStatusList(): List<Long> = listOf(UNREAD, READING, COMPLETED)
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
UNREAD -> MR.strings.unread UNREAD -> MR.strings.unread
READING -> MR.strings.reading READING -> MR.strings.reading
COMPLETED -> MR.strings.completed COMPLETED -> MR.strings.completed
else -> null else -> null
} }
override fun getReadingStatus(): Int = READING override fun getReadingStatus(): Long = READING
override fun getRereadingStatus(): Int = -1 override fun getRereadingStatus(): Long = -1
override fun getCompletionStatus(): Int = COMPLETED override fun getCompletionStatus(): Long = COMPLETED
override fun getScoreList(): ImmutableList<String> = persistentListOf() override fun getScoreList(): ImmutableList<String> = persistentListOf()
@ -50,7 +50,7 @@ class Suwayomi(id: Long) : BaseTracker(id, "Suwayomi"), EnhancedTracker {
override suspend fun update(track: Track, didReadChapter: Boolean): Track { override suspend fun update(track: Track, didReadChapter: Boolean): Track {
if (track.status != COMPLETED) { if (track.status != COMPLETED) {
if (didReadChapter) { if (didReadChapter) {
if (track.last_chapter_read.toInt() == track.total_chapters && track.total_chapters > 0) { if (track.last_chapter_read.toLong() == track.total_chapters && track.total_chapters > 0) {
track.status = COMPLETED track.status = COMPLETED
} else { } else {
track.status = READING track.status = READING

View file

@ -66,9 +66,9 @@ class SuwayomiApi(private val trackId: Long) {
cover_url = "$url/thumbnail" cover_url = "$url/thumbnail"
summary = manga.description.orEmpty() summary = manga.description.orEmpty()
tracking_url = url tracking_url = url
total_chapters = manga.chapterCount.toInt() total_chapters = manga.chapterCount
publishing_status = manga.status publishing_status = manga.status
last_chapter_read = manga.lastChapterRead?.chapterNumber ?: 0F last_chapter_read = manga.lastChapterRead?.chapterNumber ?: 0.0
status = when (manga.unreadCount) { status = when (manga.unreadCount) {
manga.chapterCount -> Suwayomi.UNREAD manga.chapterCount -> Suwayomi.UNREAD
0L -> Suwayomi.COMPLETED 0L -> Suwayomi.COMPLETED

View file

@ -64,7 +64,7 @@ data class ChapterDataClass(
val url: String, val url: String,
val name: String, val name: String,
val uploadDate: Long, val uploadDate: Long,
val chapterNumber: Float, val chapterNumber: Double,
val scanlator: String?, val scanlator: String?,
val mangaId: Int, val mangaId: Int,

View file

@ -285,13 +285,13 @@ private data class TrackStatusSelectorScreen(
private class Model( private class Model(
private val track: Track, private val track: Track,
private val tracker: Tracker, private val tracker: Tracker,
) : StateScreenModel<Model.State>(State(track.status.toInt())) { ) : StateScreenModel<Model.State>(State(track.status)) {
fun getSelections(): Map<Int, StringResource?> { fun getSelections(): Map<Long, StringResource?> {
return tracker.getStatusList().associateWith { tracker.getStatus(it) } return tracker.getStatusList().associateWith { tracker.getStatus(it) }
} }
fun setSelection(selection: Int) { fun setSelection(selection: Long) {
mutableState.update { it.copy(selection = selection) } mutableState.update { it.copy(selection = selection) }
} }
@ -303,7 +303,7 @@ private data class TrackStatusSelectorScreen(
@Immutable @Immutable
data class State( data class State(
val selection: Int, val selection: Long,
) )
} }
} }

View file

@ -18,10 +18,10 @@ data class DummyTracker(
override val isLoggedIn: Boolean = false, override val isLoggedIn: Boolean = false,
val valLogoColor: Int = Color.rgb(18, 25, 35), val valLogoColor: Int = Color.rgb(18, 25, 35),
val valLogo: Int = R.drawable.ic_tracker_anilist, val valLogo: Int = R.drawable.ic_tracker_anilist,
val valStatuses: List<Int> = (1..6).toList(), val valStatuses: List<Long> = (1L..6L).toList(),
val valReadingStatus: Int = 1, val valReadingStatus: Long = 1L,
val valRereadingStatus: Int = 1, val valRereadingStatus: Long = 1L,
val valCompletionStatus: Int = 2, val valCompletionStatus: Long = 2L,
val valScoreList: ImmutableList<String> = (0..10).map(Int::toString).toImmutableList(), val valScoreList: ImmutableList<String> = (0..10).map(Int::toString).toImmutableList(),
val val10PointScore: Double = 5.4, val val10PointScore: Double = 5.4,
val valSearchResults: List<TrackSearch> = listOf(), val valSearchResults: List<TrackSearch> = listOf(),
@ -34,29 +34,29 @@ data class DummyTracker(
override fun getLogo(): Int = valLogo override fun getLogo(): Int = valLogo
override fun getStatusList(): List<Int> = valStatuses override fun getStatusList(): List<Long> = valStatuses
override fun getStatus(status: Int): StringResource? = when (status) { override fun getStatus(status: Long): StringResource? = when (status) {
1 -> MR.strings.reading 1L -> MR.strings.reading
2 -> MR.strings.plan_to_read 2L -> MR.strings.plan_to_read
3 -> MR.strings.completed 3L -> MR.strings.completed
4 -> MR.strings.on_hold 4L -> MR.strings.on_hold
5 -> MR.strings.dropped 5L -> MR.strings.dropped
6 -> MR.strings.repeating 6L -> MR.strings.repeating
else -> null else -> null
} }
override fun getReadingStatus(): Int = valReadingStatus override fun getReadingStatus(): Long = valReadingStatus
override fun getRereadingStatus(): Int = valRereadingStatus override fun getRereadingStatus(): Long = valRereadingStatus
override fun getCompletionStatus(): Int = valCompletionStatus override fun getCompletionStatus(): Long = valCompletionStatus
override fun getScoreList(): ImmutableList<String> = valScoreList override fun getScoreList(): ImmutableList<String> = valScoreList
override fun get10PointScore(track: Track): Double = val10PointScore override fun get10PointScore(track: Track): Double = val10PointScore
override fun indexToScore(index: Int): Float = getScoreList()[index].toFloat() override fun indexToScore(index: Int): Double = getScoreList()[index].toDouble()
override fun displayScore(track: Track): String = override fun displayScore(track: Track): String =
track.score.toString() track.score.toString()
@ -94,7 +94,7 @@ data class DummyTracker(
override suspend fun setRemoteStatus( override suspend fun setRemoteStatus(
track: eu.kanade.tachiyomi.data.database.models.Track, track: eu.kanade.tachiyomi.data.database.models.Track,
status: Int, status: Long,
) = Unit ) = Unit
override suspend fun setRemoteLastChapterRead( override suspend fun setRemoteLastChapterRead(