Decoupled Tracker Interface (#10042)
Split out Tracker to interface and created simple dummy instance for previews
This commit is contained in:
parent
489d22720a
commit
3a35c13575
11 changed files with 222 additions and 173 deletions
169
app/src/main/java/eu/kanade/tachiyomi/data/track/BaseTracker.kt
Normal file
169
app/src/main/java/eu/kanade/tachiyomi/data/track/BaseTracker.kt
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
package eu.kanade.tachiyomi.data.track
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.annotation.CallSuper
|
||||||
|
import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack
|
||||||
|
import eu.kanade.domain.track.model.toDbTrack
|
||||||
|
import eu.kanade.domain.track.model.toDomainTrack
|
||||||
|
import eu.kanade.domain.track.service.TrackPreferences
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
|
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
|
||||||
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import logcat.LogPriority
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import tachiyomi.core.util.lang.withIOContext
|
||||||
|
import tachiyomi.core.util.lang.withUIContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.chapter.interactor.GetChapterByMangaId
|
||||||
|
import tachiyomi.domain.history.interactor.GetHistory
|
||||||
|
import tachiyomi.domain.track.interactor.InsertTrack
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.time.ZoneOffset
|
||||||
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
|
abstract class BaseTracker(
|
||||||
|
override val id: Long,
|
||||||
|
override val name: String,
|
||||||
|
) : Tracker {
|
||||||
|
|
||||||
|
val trackPreferences: TrackPreferences by injectLazy()
|
||||||
|
val networkService: NetworkHelper by injectLazy()
|
||||||
|
private val insertTrack: InsertTrack by injectLazy()
|
||||||
|
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack by injectLazy()
|
||||||
|
|
||||||
|
override val client: OkHttpClient
|
||||||
|
get() = networkService.client
|
||||||
|
|
||||||
|
// Application and remote support for reading dates
|
||||||
|
override val supportsReadingDates: Boolean = false
|
||||||
|
|
||||||
|
// TODO: Store all scores as 10 point in the future maybe?
|
||||||
|
override fun get10PointScore(track: DomainTrack): Double {
|
||||||
|
return track.score
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun indexToScore(index: Int): Float {
|
||||||
|
return index.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
override fun logout() {
|
||||||
|
trackPreferences.setCredentials(this, "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isLoggedIn: Boolean
|
||||||
|
get() = getUsername().isNotEmpty() &&
|
||||||
|
getPassword().isNotEmpty()
|
||||||
|
|
||||||
|
override fun getUsername() = trackPreferences.trackUsername(this).get()
|
||||||
|
|
||||||
|
override fun getPassword() = trackPreferences.trackPassword(this).get()
|
||||||
|
|
||||||
|
override fun saveCredentials(username: String, password: String) {
|
||||||
|
trackPreferences.setCredentials(this, username, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: move this to an interactor, and update all trackers based on common data
|
||||||
|
override suspend fun register(item: Track, mangaId: Long) {
|
||||||
|
item.manga_id = mangaId
|
||||||
|
try {
|
||||||
|
withIOContext {
|
||||||
|
val allChapters = Injekt.get<GetChapterByMangaId>().await(mangaId)
|
||||||
|
val hasReadChapters = allChapters.any { it.read }
|
||||||
|
bind(item, hasReadChapters)
|
||||||
|
|
||||||
|
var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
|
||||||
|
|
||||||
|
insertTrack.await(track)
|
||||||
|
|
||||||
|
// TODO: merge into [SyncChapterProgressWithTrack]?
|
||||||
|
// Update chapter progress if newer chapters marked read locally
|
||||||
|
if (hasReadChapters) {
|
||||||
|
val latestLocalReadChapterNumber = allChapters
|
||||||
|
.sortedBy { it.chapterNumber }
|
||||||
|
.takeWhile { it.read }
|
||||||
|
.lastOrNull()
|
||||||
|
?.chapterNumber ?: -1.0
|
||||||
|
|
||||||
|
if (latestLocalReadChapterNumber > track.lastChapterRead) {
|
||||||
|
track = track.copy(
|
||||||
|
lastChapterRead = latestLocalReadChapterNumber,
|
||||||
|
)
|
||||||
|
setRemoteLastChapterRead(track.toDbTrack(), latestLocalReadChapterNumber.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track.startDate <= 0) {
|
||||||
|
val firstReadChapterDate = Injekt.get<GetHistory>().await(mangaId)
|
||||||
|
.sortedBy { it.readAt }
|
||||||
|
.firstOrNull()
|
||||||
|
?.readAt
|
||||||
|
|
||||||
|
firstReadChapterDate?.let {
|
||||||
|
val startDate = firstReadChapterDate.time.convertEpochMillisZone(ZoneOffset.systemDefault(), ZoneOffset.UTC)
|
||||||
|
track = track.copy(
|
||||||
|
startDate = startDate,
|
||||||
|
)
|
||||||
|
setRemoteStartDate(track.toDbTrack(), startDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncChapterProgressWithTrack.await(mangaId, track, this@BaseTracker)
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
withUIContext { Injekt.get<Application>().toast(e.message) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setRemoteStatus(track: Track, status: Int) {
|
||||||
|
track.status = status
|
||||||
|
if (track.status == getCompletionStatus() && track.total_chapters != 0) {
|
||||||
|
track.last_chapter_read = track.total_chapters.toFloat()
|
||||||
|
}
|
||||||
|
withIOContext { updateRemote(track) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int) {
|
||||||
|
if (track.last_chapter_read == 0f && track.last_chapter_read < chapterNumber && track.status != getRereadingStatus()) {
|
||||||
|
track.status = getReadingStatus()
|
||||||
|
}
|
||||||
|
track.last_chapter_read = chapterNumber.toFloat()
|
||||||
|
if (track.total_chapters != 0 && track.last_chapter_read.toInt() == track.total_chapters) {
|
||||||
|
track.status = getCompletionStatus()
|
||||||
|
track.finished_reading_date = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
withIOContext { updateRemote(track) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setRemoteScore(track: Track, scoreString: String) {
|
||||||
|
track.score = indexToScore(getScoreList().indexOf(scoreString))
|
||||||
|
withIOContext { updateRemote(track) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setRemoteStartDate(track: Track, epochMillis: Long) {
|
||||||
|
track.started_reading_date = epochMillis
|
||||||
|
withIOContext { updateRemote(track) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun setRemoteFinishDate(track: Track, epochMillis: Long) {
|
||||||
|
track.finished_reading_date = epochMillis
|
||||||
|
withIOContext { updateRemote(track) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun updateRemote(track: Track) {
|
||||||
|
withIOContext {
|
||||||
|
try {
|
||||||
|
update(track)
|
||||||
|
track.toDomainTrack(idRequired = false)?.let {
|
||||||
|
insertTrack.await(it)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logcat(LogPriority.ERROR, e) { "Failed to update remote track data id=$id" }
|
||||||
|
withUIContext { Injekt.get<Application>().toast(e.message) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,201 +1,81 @@
|
||||||
package eu.kanade.tachiyomi.data.track
|
package eu.kanade.tachiyomi.data.track
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack
|
|
||||||
import eu.kanade.domain.track.model.toDbTrack
|
|
||||||
import eu.kanade.domain.track.model.toDomainTrack
|
|
||||||
import eu.kanade.domain.track.service.TrackPreferences
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
|
||||||
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
|
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
|
||||||
import logcat.LogPriority
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import tachiyomi.core.util.lang.withIOContext
|
|
||||||
import tachiyomi.core.util.lang.withUIContext
|
|
||||||
import tachiyomi.core.util.system.logcat
|
|
||||||
import tachiyomi.domain.chapter.interactor.GetChapterByMangaId
|
|
||||||
import tachiyomi.domain.history.interactor.GetHistory
|
|
||||||
import tachiyomi.domain.track.interactor.InsertTrack
|
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import java.time.ZoneOffset
|
|
||||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
|
||||||
|
|
||||||
abstract class Tracker(val id: Long, val name: String) {
|
interface Tracker {
|
||||||
|
|
||||||
val trackPreferences: TrackPreferences by injectLazy()
|
val id: Long
|
||||||
val networkService: NetworkHelper by injectLazy()
|
|
||||||
private val insertTrack: InsertTrack by injectLazy()
|
|
||||||
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack by injectLazy()
|
|
||||||
|
|
||||||
open val client: OkHttpClient
|
val name: String
|
||||||
get() = networkService.client
|
|
||||||
|
val client: OkHttpClient
|
||||||
|
|
||||||
// Application and remote support for reading dates
|
// Application and remote support for reading dates
|
||||||
open val supportsReadingDates: Boolean = false
|
val supportsReadingDates: Boolean
|
||||||
|
|
||||||
@DrawableRes
|
|
||||||
abstract fun getLogo(): Int
|
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
abstract fun getLogoColor(): Int
|
fun getLogoColor(): Int
|
||||||
|
|
||||||
abstract fun getStatusList(): List<Int>
|
@DrawableRes
|
||||||
|
fun getLogo(): Int
|
||||||
|
|
||||||
|
fun getStatusList(): List<Int>
|
||||||
|
|
||||||
@StringRes
|
@StringRes
|
||||||
abstract fun getStatus(status: Int): Int?
|
fun getStatus(status: Int): Int?
|
||||||
|
|
||||||
abstract fun getReadingStatus(): Int
|
fun getReadingStatus(): Int
|
||||||
|
|
||||||
abstract fun getRereadingStatus(): Int
|
fun getRereadingStatus(): Int
|
||||||
|
|
||||||
abstract fun getCompletionStatus(): Int
|
fun getCompletionStatus(): Int
|
||||||
|
|
||||||
abstract fun getScoreList(): List<String>
|
fun getScoreList(): List<String>
|
||||||
|
|
||||||
// TODO: Store all scores as 10 point in the future maybe?
|
// TODO: Store all scores as 10 point in the future maybe?
|
||||||
open fun get10PointScore(track: DomainTrack): Double {
|
fun get10PointScore(track: tachiyomi.domain.track.model.Track): Double
|
||||||
return track.score
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun indexToScore(index: Int): Float {
|
fun indexToScore(index: Int): Float
|
||||||
return index.toFloat()
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun displayScore(track: Track): String
|
fun displayScore(track: Track): String
|
||||||
|
|
||||||
abstract suspend fun update(track: Track, didReadChapter: Boolean = false): Track
|
suspend fun update(track: Track, didReadChapter: Boolean = false): Track
|
||||||
|
|
||||||
abstract suspend fun bind(track: Track, hasReadChapters: Boolean = false): Track
|
suspend fun bind(track: Track, hasReadChapters: Boolean = false): Track
|
||||||
|
|
||||||
abstract suspend fun search(query: String): List<TrackSearch>
|
suspend fun search(query: String): List<TrackSearch>
|
||||||
|
|
||||||
abstract suspend fun refresh(track: Track): Track
|
suspend fun refresh(track: Track): Track
|
||||||
|
|
||||||
abstract suspend fun login(username: String, password: String)
|
suspend fun login(username: String, password: String)
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
open fun logout() {
|
fun logout()
|
||||||
trackPreferences.setCredentials(this, "", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val isLoggedIn: Boolean
|
val isLoggedIn: Boolean
|
||||||
get() = getUsername().isNotEmpty() &&
|
|
||||||
getPassword().isNotEmpty()
|
|
||||||
|
|
||||||
fun getUsername() = trackPreferences.trackUsername(this).get()
|
fun getUsername(): String
|
||||||
|
|
||||||
fun getPassword() = trackPreferences.trackPassword(this).get()
|
fun getPassword(): String
|
||||||
|
|
||||||
fun saveCredentials(username: String, password: String) {
|
fun saveCredentials(username: String, password: String)
|
||||||
trackPreferences.setCredentials(this, username, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
||||||
item.manga_id = mangaId
|
|
||||||
try {
|
|
||||||
withIOContext {
|
|
||||||
val allChapters = Injekt.get<GetChapterByMangaId>().await(mangaId)
|
|
||||||
val hasReadChapters = allChapters.any { it.read }
|
|
||||||
bind(item, hasReadChapters)
|
|
||||||
|
|
||||||
var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
|
suspend fun setRemoteStatus(track: Track, status: Int)
|
||||||
|
|
||||||
insertTrack.await(track)
|
suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int)
|
||||||
|
|
||||||
// TODO: merge into [SyncChapterProgressWithTrack]?
|
suspend fun setRemoteScore(track: Track, scoreString: String)
|
||||||
// Update chapter progress if newer chapters marked read locally
|
|
||||||
if (hasReadChapters) {
|
|
||||||
val latestLocalReadChapterNumber = allChapters
|
|
||||||
.sortedBy { it.chapterNumber }
|
|
||||||
.takeWhile { it.read }
|
|
||||||
.lastOrNull()
|
|
||||||
?.chapterNumber ?: -1.0
|
|
||||||
|
|
||||||
if (latestLocalReadChapterNumber > track.lastChapterRead) {
|
suspend fun setRemoteStartDate(track: Track, epochMillis: Long)
|
||||||
track = track.copy(
|
|
||||||
lastChapterRead = latestLocalReadChapterNumber,
|
|
||||||
)
|
|
||||||
setRemoteLastChapterRead(track.toDbTrack(), latestLocalReadChapterNumber.toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (track.startDate <= 0) {
|
suspend fun setRemoteFinishDate(track: Track, epochMillis: Long)
|
||||||
val firstReadChapterDate = Injekt.get<GetHistory>().await(mangaId)
|
|
||||||
.sortedBy { it.readAt }
|
|
||||||
.firstOrNull()
|
|
||||||
?.readAt
|
|
||||||
|
|
||||||
firstReadChapterDate?.let {
|
|
||||||
val startDate = firstReadChapterDate.time.convertEpochMillisZone(ZoneOffset.systemDefault(), ZoneOffset.UTC)
|
|
||||||
track = track.copy(
|
|
||||||
startDate = startDate,
|
|
||||||
)
|
|
||||||
setRemoteStartDate(track.toDbTrack(), startDate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
syncChapterProgressWithTrack.await(mangaId, track, this@Tracker)
|
|
||||||
}
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
withUIContext { Injekt.get<Application>().toast(e.message) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setRemoteStatus(track: Track, status: Int) {
|
|
||||||
track.status = status
|
|
||||||
if (track.status == getCompletionStatus() && track.total_chapters != 0) {
|
|
||||||
track.last_chapter_read = track.total_chapters.toFloat()
|
|
||||||
}
|
|
||||||
withIOContext { updateRemote(track) }
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setRemoteLastChapterRead(track: Track, chapterNumber: Int) {
|
|
||||||
if (track.last_chapter_read == 0f && track.last_chapter_read < chapterNumber && track.status != getRereadingStatus()) {
|
|
||||||
track.status = getReadingStatus()
|
|
||||||
}
|
|
||||||
track.last_chapter_read = chapterNumber.toFloat()
|
|
||||||
if (track.total_chapters != 0 && track.last_chapter_read.toInt() == track.total_chapters) {
|
|
||||||
track.status = getCompletionStatus()
|
|
||||||
track.finished_reading_date = System.currentTimeMillis()
|
|
||||||
}
|
|
||||||
withIOContext { updateRemote(track) }
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setRemoteScore(track: Track, scoreString: String) {
|
|
||||||
track.score = indexToScore(getScoreList().indexOf(scoreString))
|
|
||||||
withIOContext { updateRemote(track) }
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setRemoteStartDate(track: Track, epochMillis: Long) {
|
|
||||||
track.started_reading_date = epochMillis
|
|
||||||
withIOContext { updateRemote(track) }
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setRemoteFinishDate(track: Track, epochMillis: Long) {
|
|
||||||
track.finished_reading_date = epochMillis
|
|
||||||
withIOContext { updateRemote(track) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun updateRemote(track: Track) {
|
|
||||||
withIOContext {
|
|
||||||
try {
|
|
||||||
update(track)
|
|
||||||
track.toDomainTrack(idRequired = false)?.let {
|
|
||||||
insertTrack.await(it)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logcat(LogPriority.ERROR, e) { "Failed to update remote track data id=$id" }
|
|
||||||
withUIContext { Injekt.get<Application>().toast(e.message) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
class Anilist(id: Long) : Tracker(id, "AniList"), DeletableTracker {
|
class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val READING = 1
|
const val READING = 1
|
||||||
|
|
|
@ -4,13 +4,13 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class Bangumi(id: Long) : Tracker(id, "Bangumi") {
|
class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
@ -16,7 +16,7 @@ import uy.kohesive.injekt.injectLazy
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
class Kavita(id: Long) : Tracker(id, "Kavita"), EnhancedTracker {
|
class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val UNREAD = 1
|
const val UNREAD = 1
|
||||||
|
|
|
@ -4,15 +4,15 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
|
|
||||||
class Kitsu(id: Long) : Tracker(id, "Kitsu"), DeletableTracker {
|
class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val READING = 1
|
const val READING = 1
|
||||||
|
|
|
@ -4,8 +4,8 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import okhttp3.Dns
|
import okhttp3.Dns
|
||||||
|
@ -13,7 +13,7 @@ import okhttp3.OkHttpClient
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
class Komga(id: Long) : Tracker(id, "Komga"), EnhancedTracker {
|
class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val UNREAD = 1
|
const val UNREAD = 1
|
||||||
|
|
|
@ -4,13 +4,13 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo
|
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo
|
||||||
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch
|
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
|
|
||||||
class MangaUpdates(id: Long) : Tracker(id, "MangaUpdates"), DeletableTracker {
|
class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val READING_LIST = 0
|
const val READING_LIST = 0
|
||||||
|
|
|
@ -4,14 +4,14 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class MyAnimeList(id: Long) : Tracker(id, "MyAnimeList"), DeletableTracker {
|
class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val READING = 1
|
const val READING = 1
|
||||||
|
|
|
@ -4,14 +4,14 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class Shikimori(id: Long) : Tracker(id, "Shikimori"), DeletableTracker {
|
class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val READING = 1
|
const val READING = 1
|
||||||
|
|
|
@ -4,14 +4,14 @@ import android.graphics.Color
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import tachiyomi.domain.manga.model.Manga as DomainManga
|
import tachiyomi.domain.manga.model.Manga as DomainManga
|
||||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
class Suwayomi(id: Long) : Tracker(id, "Suwayomi"), EnhancedTracker {
|
class Suwayomi(id: Long) : BaseTracker(id, "Suwayomi"), EnhancedTracker {
|
||||||
|
|
||||||
val api by lazy { SuwayomiApi(id) }
|
val api by lazy { SuwayomiApi(id) }
|
||||||
|
|
||||||
|
|
Reference in a new issue