Remove need for SQLDelight primitive adapters
This commit is contained in:
parent
6a558ad119
commit
cd91ea9b77
@ -170,7 +170,6 @@ dependencies {
|
|||||||
implementation(androidx.paging.compose)
|
implementation(androidx.paging.compose)
|
||||||
|
|
||||||
implementation(libs.bundles.sqlite)
|
implementation(libs.bundles.sqlite)
|
||||||
implementation(libs.sqldelight.primitive.adapters)
|
|
||||||
|
|
||||||
implementation(kotlinx.reflect)
|
implementation(kotlinx.reflect)
|
||||||
|
|
||||||
|
@ -151,9 +151,9 @@ class SyncChaptersWithSource(
|
|||||||
|
|
||||||
val reAdded = mutableListOf<Chapter>()
|
val reAdded = mutableListOf<Chapter>()
|
||||||
|
|
||||||
val deletedChapterNumbers = TreeSet<Float>()
|
val deletedChapterNumbers = TreeSet<Double>()
|
||||||
val deletedReadChapterNumbers = TreeSet<Float>()
|
val deletedReadChapterNumbers = TreeSet<Double>()
|
||||||
val deletedBookmarkedChapterNumbers = TreeSet<Float>()
|
val deletedBookmarkedChapterNumbers = TreeSet<Double>()
|
||||||
|
|
||||||
toDelete.forEach { chapter ->
|
toDelete.forEach { chapter ->
|
||||||
if (chapter.read) deletedReadChapterNumbers.add(chapter.chapterNumber)
|
if (chapter.read) deletedReadChapterNumbers.add(chapter.chapterNumber)
|
||||||
|
@ -12,7 +12,7 @@ fun Chapter.toSChapter(): SChapter {
|
|||||||
it.url = url
|
it.url = url
|
||||||
it.name = name
|
it.name = name
|
||||||
it.date_upload = dateUpload
|
it.date_upload = dateUpload
|
||||||
it.chapter_number = chapterNumber
|
it.chapter_number = chapterNumber.toFloat()
|
||||||
it.scanlator = scanlator
|
it.scanlator = scanlator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ fun Chapter.copyFromSChapter(sChapter: SChapter): Chapter {
|
|||||||
name = sChapter.name,
|
name = sChapter.name,
|
||||||
url = sChapter.url,
|
url = sChapter.url,
|
||||||
dateUpload = sChapter.date_upload,
|
dateUpload = sChapter.date_upload,
|
||||||
chapterNumber = sChapter.chapter_number,
|
chapterNumber = sChapter.chapter_number.toDouble(),
|
||||||
scanlator = sChapter.scanlator?.ifBlank { null },
|
scanlator = sChapter.scanlator?.ifBlank { null },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -48,6 +48,6 @@ fun Chapter.toDbChapter(): DbChapter = ChapterImpl().also {
|
|||||||
it.last_page_read = lastPageRead.toInt()
|
it.last_page_read = lastPageRead.toInt()
|
||||||
it.date_fetch = dateFetch
|
it.date_fetch = dateFetch
|
||||||
it.date_upload = dateUpload
|
it.date_upload = dateUpload
|
||||||
it.chapter_number = chapterNumber
|
it.chapter_number = chapterNumber.toFloat()
|
||||||
it.source_order = sourceOrder.toInt()
|
it.source_order = sourceOrder.toInt()
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ fun getComicInfo(manga: Manga, chapter: Chapter, chapterUrl: String, categories:
|
|||||||
title = ComicInfo.Title(chapter.name),
|
title = ComicInfo.Title(chapter.name),
|
||||||
series = ComicInfo.Series(manga.title),
|
series = ComicInfo.Series(manga.title),
|
||||||
number = chapter.chapterNumber.takeIf { it >= 0 }?.let {
|
number = chapter.chapterNumber.takeIf { it >= 0 }?.let {
|
||||||
if ((it.rem(1) == 0.0F)) {
|
if ((it.rem(1) == 0.0)) {
|
||||||
ComicInfo.Number(it.toInt().toString())
|
ComicInfo.Number(it.toInt().toString())
|
||||||
} else {
|
} else {
|
||||||
ComicInfo.Number(it.toString())
|
ComicInfo.Number(it.toString())
|
||||||
|
@ -22,7 +22,7 @@ fun Track.toDbTrack(): DbTrack = DbTrack.create(syncId).also {
|
|||||||
it.last_chapter_read = lastChapterRead.toFloat()
|
it.last_chapter_read = lastChapterRead.toFloat()
|
||||||
it.total_chapters = totalChapters.toInt()
|
it.total_chapters = totalChapters.toInt()
|
||||||
it.status = status.toInt()
|
it.status = status.toInt()
|
||||||
it.score = score
|
it.score = score.toFloat()
|
||||||
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
|
||||||
@ -40,7 +40,7 @@ fun DbTrack.toDomainTrack(idRequired: Boolean = true): Track? {
|
|||||||
lastChapterRead = last_chapter_read.toDouble(),
|
lastChapterRead = last_chapter_read.toDouble(),
|
||||||
totalChapters = total_chapters.toLong(),
|
totalChapters = total_chapters.toLong(),
|
||||||
status = status.toLong(),
|
status = status.toLong(),
|
||||||
score = score,
|
score = score.toDouble(),
|
||||||
remoteUrl = tracking_url,
|
remoteUrl = tracking_url,
|
||||||
startDate = started_reading_date,
|
startDate = started_reading_date,
|
||||||
finishDate = finished_reading_date,
|
finishDate = finished_reading_date,
|
||||||
|
@ -98,7 +98,7 @@ fun TrackInfoDialogHome(
|
|||||||
},
|
},
|
||||||
onChaptersClick = { onChapterClick(item) },
|
onChaptersClick = { onChapterClick(item) },
|
||||||
score = item.service.displayScore(item.track.toDbTrack())
|
score = item.service.displayScore(item.track.toDbTrack())
|
||||||
.takeIf { supportsScoring && item.track.score != 0F },
|
.takeIf { supportsScoring && item.track.score != 0.0 },
|
||||||
onScoreClick = { onScoreClick(item) }
|
onScoreClick = { onScoreClick(item) }
|
||||||
.takeIf { supportsScoring },
|
.takeIf { supportsScoring },
|
||||||
startDate = remember(item.track.startDate) { dateFormat.format(item.track.startDate) }
|
startDate = remember(item.track.startDate) { dateFormat.format(item.track.startDate) }
|
||||||
|
@ -8,6 +8,6 @@ private val formatter = DecimalFormat(
|
|||||||
DecimalFormatSymbols().apply { decimalSeparator = '.' },
|
DecimalFormatSymbols().apply { decimalSeparator = '.' },
|
||||||
)
|
)
|
||||||
|
|
||||||
fun formatChapterNumber(chapterNumber: Float): String {
|
fun formatChapterNumber(chapterNumber: Double): String {
|
||||||
return formatter.format(chapterNumber)
|
return formatter.format(chapterNumber)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import android.os.Build
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
|
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
|
||||||
import app.cash.sqldelight.adapter.primitive.FloatColumnAdapter
|
|
||||||
import app.cash.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
|
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
|
||||||
import eu.kanade.domain.base.BasePreferences
|
import eu.kanade.domain.base.BasePreferences
|
||||||
@ -38,15 +37,13 @@ import tachiyomi.core.preference.PreferenceStore
|
|||||||
import tachiyomi.core.provider.AndroidBackupFolderProvider
|
import tachiyomi.core.provider.AndroidBackupFolderProvider
|
||||||
import tachiyomi.core.provider.AndroidDownloadFolderProvider
|
import tachiyomi.core.provider.AndroidDownloadFolderProvider
|
||||||
import tachiyomi.data.AndroidDatabaseHandler
|
import tachiyomi.data.AndroidDatabaseHandler
|
||||||
import tachiyomi.data.Chapters
|
|
||||||
import tachiyomi.data.Database
|
import tachiyomi.data.Database
|
||||||
import tachiyomi.data.DatabaseHandler
|
import tachiyomi.data.DatabaseHandler
|
||||||
|
import tachiyomi.data.DateColumnAdapter
|
||||||
import tachiyomi.data.History
|
import tachiyomi.data.History
|
||||||
import tachiyomi.data.Manga_sync
|
|
||||||
import tachiyomi.data.Mangas
|
import tachiyomi.data.Mangas
|
||||||
import tachiyomi.data.dateAdapter
|
import tachiyomi.data.StringListColumnAdapter
|
||||||
import tachiyomi.data.listOfStringsAdapter
|
import tachiyomi.data.UpdateStrategyColumnAdapter
|
||||||
import tachiyomi.data.updateStrategyAdapter
|
|
||||||
import tachiyomi.domain.backup.service.BackupPreferences
|
import tachiyomi.domain.backup.service.BackupPreferences
|
||||||
import tachiyomi.domain.download.service.DownloadPreferences
|
import tachiyomi.domain.download.service.DownloadPreferences
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
@ -93,18 +90,12 @@ class AppModule(val app: Application) : InjektModule {
|
|||||||
addSingletonFactory {
|
addSingletonFactory {
|
||||||
Database(
|
Database(
|
||||||
driver = get(),
|
driver = get(),
|
||||||
chaptersAdapter = Chapters.Adapter(
|
|
||||||
chapter_numberAdapter = FloatColumnAdapter,
|
|
||||||
),
|
|
||||||
historyAdapter = History.Adapter(
|
historyAdapter = History.Adapter(
|
||||||
last_readAdapter = dateAdapter,
|
last_readAdapter = DateColumnAdapter,
|
||||||
),
|
|
||||||
manga_syncAdapter = Manga_sync.Adapter(
|
|
||||||
scoreAdapter = FloatColumnAdapter,
|
|
||||||
),
|
),
|
||||||
mangasAdapter = Mangas.Adapter(
|
mangasAdapter = Mangas.Adapter(
|
||||||
genreAdapter = listOfStringsAdapter,
|
genreAdapter = StringListColumnAdapter,
|
||||||
update_strategyAdapter = updateStrategyAdapter,
|
update_strategyAdapter = UpdateStrategyColumnAdapter,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,11 @@ import logcat.LogPriority
|
|||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.gzip
|
import okio.gzip
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import tachiyomi.core.util.lang.toLong
|
|
||||||
import tachiyomi.core.util.system.logcat
|
import tachiyomi.core.util.system.logcat
|
||||||
import tachiyomi.data.DatabaseHandler
|
import tachiyomi.data.DatabaseHandler
|
||||||
import tachiyomi.data.Manga_sync
|
import tachiyomi.data.Manga_sync
|
||||||
import tachiyomi.data.Mangas
|
import tachiyomi.data.Mangas
|
||||||
import tachiyomi.data.updateStrategyAdapter
|
import tachiyomi.data.UpdateStrategyColumnAdapter
|
||||||
import tachiyomi.domain.backup.service.BackupPreferences
|
import tachiyomi.domain.backup.service.BackupPreferences
|
||||||
import tachiyomi.domain.category.interactor.GetCategories
|
import tachiyomi.domain.category.interactor.GetCategories
|
||||||
import tachiyomi.domain.category.model.Category
|
import tachiyomi.domain.category.model.Category
|
||||||
@ -415,7 +414,7 @@ class BackupManager(
|
|||||||
track.last_chapter_read,
|
track.last_chapter_read,
|
||||||
track.total_chapters,
|
track.total_chapters,
|
||||||
track.status,
|
track.status,
|
||||||
track.score.toDouble(),
|
track.score,
|
||||||
track.remote_url,
|
track.remote_url,
|
||||||
track.start_date,
|
track.start_date,
|
||||||
track.finish_date,
|
track.finish_date,
|
||||||
@ -536,7 +535,7 @@ class BackupManager(
|
|||||||
coverLastModified = manga.coverLastModified,
|
coverLastModified = manga.coverLastModified,
|
||||||
dateAdded = manga.dateAdded,
|
dateAdded = manga.dateAdded,
|
||||||
mangaId = manga.id,
|
mangaId = manga.id,
|
||||||
updateStrategy = manga.updateStrategy.let(updateStrategyAdapter::encode),
|
updateStrategy = manga.updateStrategy.let(UpdateStrategyColumnAdapter::encode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return manga.id
|
return manga.id
|
||||||
|
@ -26,7 +26,7 @@ data class BackupChapter(
|
|||||||
return Chapter.create().copy(
|
return Chapter.create().copy(
|
||||||
url = this@BackupChapter.url,
|
url = this@BackupChapter.url,
|
||||||
name = this@BackupChapter.name,
|
name = this@BackupChapter.name,
|
||||||
chapterNumber = this@BackupChapter.chapterNumber,
|
chapterNumber = this@BackupChapter.chapterNumber.toDouble(),
|
||||||
scanlator = this@BackupChapter.scanlator,
|
scanlator = this@BackupChapter.scanlator,
|
||||||
read = this@BackupChapter.read,
|
read = this@BackupChapter.read,
|
||||||
bookmark = this@BackupChapter.bookmark,
|
bookmark = this@BackupChapter.bookmark,
|
||||||
@ -39,11 +39,11 @@ data class BackupChapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val backupChapterMapper = { _: Long, _: Long, url: String, name: String, scanlator: String?, read: Boolean, bookmark: Boolean, lastPageRead: Long, chapterNumber: Float, source_order: Long, dateFetch: Long, dateUpload: Long, lastModifiedAt: Long ->
|
val backupChapterMapper = { _: Long, _: Long, url: String, name: String, scanlator: String?, read: Boolean, bookmark: Boolean, lastPageRead: Long, chapterNumber: Double, source_order: Long, dateFetch: Long, dateUpload: Long, lastModifiedAt: Long ->
|
||||||
BackupChapter(
|
BackupChapter(
|
||||||
url = url,
|
url = url,
|
||||||
name = name,
|
name = name,
|
||||||
chapterNumber = chapterNumber,
|
chapterNumber = chapterNumber.toFloat(),
|
||||||
scanlator = scanlator,
|
scanlator = scanlator,
|
||||||
read = read,
|
read = read,
|
||||||
bookmark = bookmark,
|
bookmark = bookmark,
|
||||||
|
@ -44,7 +44,7 @@ data class BackupTracking(
|
|||||||
title = this@BackupTracking.title,
|
title = this@BackupTracking.title,
|
||||||
lastChapterRead = this@BackupTracking.lastChapterRead.toDouble(),
|
lastChapterRead = this@BackupTracking.lastChapterRead.toDouble(),
|
||||||
totalChapters = this@BackupTracking.totalChapters.toLong(),
|
totalChapters = this@BackupTracking.totalChapters.toLong(),
|
||||||
score = this@BackupTracking.score,
|
score = this@BackupTracking.score.toDouble(),
|
||||||
status = this@BackupTracking.status.toLong(),
|
status = this@BackupTracking.status.toLong(),
|
||||||
startDate = this@BackupTracking.startedReadingDate,
|
startDate = this@BackupTracking.startedReadingDate,
|
||||||
finishDate = this@BackupTracking.finishedReadingDate,
|
finishDate = this@BackupTracking.finishedReadingDate,
|
||||||
@ -54,7 +54,7 @@ data class BackupTracking(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val backupTrackMapper = {
|
val backupTrackMapper = {
|
||||||
_: Long, _: Long, syncId: Long, mediaId: Long, libraryId: Long?, title: String, lastChapterRead: Double, totalChapters: Long, status: Long, score: Float, remoteUrl: String, startDate: Long, finishDate: Long ->
|
_: Long, _: Long, syncId: Long, mediaId: Long, libraryId: Long?, title: String, lastChapterRead: Double, totalChapters: Long, status: Long, score: Double, remoteUrl: String, startDate: Long, finishDate: Long ->
|
||||||
BackupTracking(
|
BackupTracking(
|
||||||
syncId = syncId.toInt(),
|
syncId = syncId.toInt(),
|
||||||
mediaId = mediaId,
|
mediaId = mediaId,
|
||||||
@ -63,7 +63,7 @@ val backupTrackMapper = {
|
|||||||
title = title,
|
title = title,
|
||||||
lastChapterRead = lastChapterRead.toFloat(),
|
lastChapterRead = lastChapterRead.toFloat(),
|
||||||
totalChapters = totalChapters.toInt(),
|
totalChapters = totalChapters.toInt(),
|
||||||
score = score,
|
score = score.toFloat(),
|
||||||
status = status.toInt(),
|
status = status.toInt(),
|
||||||
startedReadingDate = startDate,
|
startedReadingDate = startDate,
|
||||||
finishedReadingDate = finishDate,
|
finishedReadingDate = finishDate,
|
||||||
|
@ -36,7 +36,7 @@ fun Chapter.toDomainChapter(): DomainChapter? {
|
|||||||
url = url,
|
url = url,
|
||||||
name = name,
|
name = name,
|
||||||
dateUpload = date_upload,
|
dateUpload = date_upload,
|
||||||
chapterNumber = chapter_number,
|
chapterNumber = chapter_number.toDouble(),
|
||||||
scanlator = scanlator,
|
scanlator = scanlator,
|
||||||
lastModifiedAt = last_modified,
|
lastModifiedAt = last_modified,
|
||||||
)
|
)
|
||||||
|
@ -65,7 +65,7 @@ abstract class TrackService(val id: Long) {
|
|||||||
abstract fun getScoreList(): List<String>
|
abstract 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): Float {
|
open fun get10PointScore(track: DomainTrack): Double {
|
||||||
return track.score
|
return track.score
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,9 +93,9 @@ class Anilist(id: Long) : TrackService(id), DeletableTrackService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get10PointScore(track: DomainTrack): Float {
|
override fun get10PointScore(track: DomainTrack): Double {
|
||||||
// Score is stored in 100 point format
|
// Score is stored in 100 point format
|
||||||
return track.score / 10f
|
return track.score / 10.0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun indexToScore(index: Int): Float {
|
override fun indexToScore(index: Int): Float {
|
||||||
|
@ -6,6 +6,6 @@ fun SChapter.copyFrom(other: Chapters) {
|
|||||||
name = other.name
|
name = other.name
|
||||||
url = other.url
|
url = other.url
|
||||||
date_upload = other.date_upload
|
date_upload = other.date_upload
|
||||||
chapter_number = other.chapter_number
|
chapter_number = other.chapter_number.toFloat()
|
||||||
scanlator = other.scanlator
|
scanlator = other.scanlator
|
||||||
}
|
}
|
||||||
|
@ -137,15 +137,13 @@ class StatsScreenModel(
|
|||||||
private fun getTrackMeanScore(scoredMangaTrackMap: Map<Long, List<Track>>): Double {
|
private fun getTrackMeanScore(scoredMangaTrackMap: Map<Long, List<Track>>): Double {
|
||||||
return scoredMangaTrackMap
|
return scoredMangaTrackMap
|
||||||
.map { (_, tracks) ->
|
.map { (_, tracks) ->
|
||||||
tracks.map {
|
tracks.map(::get10PointScore).average()
|
||||||
get10PointScore(it)
|
|
||||||
}.average()
|
|
||||||
}
|
}
|
||||||
.fastFilter { !it.isNaN() }
|
.fastFilter { !it.isNaN() }
|
||||||
.average()
|
.average()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun get10PointScore(track: Track): Float {
|
private fun get10PointScore(track: Track): Double {
|
||||||
val service = trackManager.getService(track.syncId)!!
|
val service = trackManager.getService(track.syncId)!!
|
||||||
return service.get10PointScore(track)
|
return service.get10PointScore(track)
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,23 @@ import app.cash.sqldelight.ColumnAdapter
|
|||||||
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
val dateAdapter = object : ColumnAdapter<Date, Long> {
|
object DateColumnAdapter : ColumnAdapter<Date, Long> {
|
||||||
override fun decode(databaseValue: Long): Date = Date(databaseValue)
|
override fun decode(databaseValue: Long): Date = Date(databaseValue)
|
||||||
override fun encode(value: Date): Long = value.time
|
override fun encode(value: Date): Long = value.time
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val listOfStringsSeparator = ", "
|
private const val LIST_OF_STRINGS_SEPARATOR = ", "
|
||||||
val listOfStringsAdapter = object : ColumnAdapter<List<String>, String> {
|
object StringListColumnAdapter : ColumnAdapter<List<String>, String> {
|
||||||
override fun decode(databaseValue: String) =
|
override fun decode(databaseValue: String) =
|
||||||
if (databaseValue.isEmpty()) {
|
if (databaseValue.isEmpty()) {
|
||||||
emptyList()
|
emptyList()
|
||||||
} else {
|
} else {
|
||||||
databaseValue.split(listOfStringsSeparator)
|
databaseValue.split(LIST_OF_STRINGS_SEPARATOR)
|
||||||
}
|
}
|
||||||
override fun encode(value: List<String>) = value.joinToString(separator = listOfStringsSeparator)
|
override fun encode(value: List<String>) = value.joinToString(separator = LIST_OF_STRINGS_SEPARATOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
val updateStrategyAdapter = object : ColumnAdapter<UpdateStrategy, Long> {
|
object UpdateStrategyColumnAdapter : ColumnAdapter<UpdateStrategy, Long> {
|
||||||
override fun decode(databaseValue: Long): UpdateStrategy =
|
override fun decode(databaseValue: Long): UpdateStrategy =
|
||||||
UpdateStrategy.entries.getOrElse(databaseValue.toInt()) { UpdateStrategy.ALWAYS_UPDATE }
|
UpdateStrategy.entries.getOrElse(databaseValue.toInt()) { UpdateStrategy.ALWAYS_UPDATE }
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package tachiyomi.data.chapter
|
|||||||
|
|
||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
|
||||||
val chapterMapper: (Long, Long, String, String, String?, Boolean, Boolean, Long, Float, Long, Long, Long, Long) -> Chapter =
|
val chapterMapper: (Long, Long, String, String, String?, Boolean, Boolean, Long, Double, Long, Long, Long, Long) -> Chapter =
|
||||||
{ id, mangaId, url, name, scanlator, read, bookmark, lastPageRead, chapterNumber, sourceOrder, dateFetch, dateUpload, lastModifiedAt ->
|
{ id, mangaId, url, name, scanlator, read, bookmark, lastPageRead, chapterNumber, sourceOrder, dateFetch, dateUpload, lastModifiedAt ->
|
||||||
Chapter(
|
Chapter(
|
||||||
id = id,
|
id = id,
|
||||||
|
@ -14,7 +14,7 @@ val historyMapper: (Long, Long, Date?, Long) -> History = { id, chapterId, readA
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val historyWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Float, Date?, Long) -> HistoryWithRelations = {
|
val historyWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Double, Date?, Long) -> HistoryWithRelations = {
|
||||||
historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
|
historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
|
||||||
HistoryWithRelations(
|
HistoryWithRelations(
|
||||||
id = historyId,
|
id = historyId,
|
||||||
|
@ -2,11 +2,10 @@ package tachiyomi.data.manga
|
|||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import tachiyomi.core.util.lang.toLong
|
|
||||||
import tachiyomi.core.util.system.logcat
|
import tachiyomi.core.util.system.logcat
|
||||||
import tachiyomi.data.DatabaseHandler
|
import tachiyomi.data.DatabaseHandler
|
||||||
import tachiyomi.data.listOfStringsAdapter
|
import tachiyomi.data.StringListColumnAdapter
|
||||||
import tachiyomi.data.updateStrategyAdapter
|
import tachiyomi.data.UpdateStrategyColumnAdapter
|
||||||
import tachiyomi.domain.library.model.LibraryManga
|
import tachiyomi.domain.library.model.LibraryManga
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
@ -129,7 +128,7 @@ class MangaRepositoryImpl(
|
|||||||
artist = value.artist,
|
artist = value.artist,
|
||||||
author = value.author,
|
author = value.author,
|
||||||
description = value.description,
|
description = value.description,
|
||||||
genre = value.genre?.let(listOfStringsAdapter::encode),
|
genre = value.genre?.let(StringListColumnAdapter::encode),
|
||||||
title = value.title,
|
title = value.title,
|
||||||
status = value.status,
|
status = value.status,
|
||||||
thumbnailUrl = value.thumbnailUrl,
|
thumbnailUrl = value.thumbnailUrl,
|
||||||
@ -143,7 +142,7 @@ class MangaRepositoryImpl(
|
|||||||
coverLastModified = value.coverLastModified,
|
coverLastModified = value.coverLastModified,
|
||||||
dateAdded = value.dateAdded,
|
dateAdded = value.dateAdded,
|
||||||
mangaId = value.id,
|
mangaId = value.id,
|
||||||
updateStrategy = value.updateStrategy?.let(updateStrategyAdapter::encode),
|
updateStrategy = value.updateStrategy?.let(UpdateStrategyColumnAdapter::encode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package tachiyomi.data.track
|
|||||||
|
|
||||||
import tachiyomi.domain.track.model.Track
|
import tachiyomi.domain.track.model.Track
|
||||||
|
|
||||||
val trackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Float, String, Long, Long) -> Track =
|
val trackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Double, String, Long, Long) -> Track =
|
||||||
{ id, mangaId, syncId, remoteId, libraryId, title, lastChapterRead, totalChapters, status, score, remoteUrl, startDate, finishDate ->
|
{ id, mangaId, syncId, remoteId, libraryId, title, lastChapterRead, totalChapters, status, score, remoteUrl, startDate, finishDate ->
|
||||||
Track(
|
Track(
|
||||||
id = id,
|
id = id,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import kotlin.Boolean;
|
import kotlin.Boolean;
|
||||||
import kotlin.Float;
|
|
||||||
|
|
||||||
CREATE TABLE chapters(
|
CREATE TABLE chapters(
|
||||||
_id INTEGER NOT NULL PRIMARY KEY,
|
_id INTEGER NOT NULL PRIMARY KEY,
|
||||||
@ -10,7 +9,7 @@ CREATE TABLE chapters(
|
|||||||
read INTEGER AS Boolean NOT NULL,
|
read INTEGER AS Boolean NOT NULL,
|
||||||
bookmark INTEGER AS Boolean NOT NULL,
|
bookmark INTEGER AS Boolean NOT NULL,
|
||||||
last_page_read INTEGER NOT NULL,
|
last_page_read INTEGER NOT NULL,
|
||||||
chapter_number REAL AS Float NOT NULL,
|
chapter_number REAL NOT NULL,
|
||||||
source_order INTEGER NOT NULL,
|
source_order INTEGER NOT NULL,
|
||||||
date_fetch INTEGER NOT NULL,
|
date_fetch INTEGER NOT NULL,
|
||||||
date_upload INTEGER NOT NULL,
|
date_upload INTEGER NOT NULL,
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import kotlin.Float;
|
|
||||||
|
|
||||||
CREATE TABLE manga_sync(
|
CREATE TABLE manga_sync(
|
||||||
_id INTEGER NOT NULL PRIMARY KEY,
|
_id INTEGER NOT NULL PRIMARY KEY,
|
||||||
manga_id INTEGER NOT NULL,
|
manga_id INTEGER NOT NULL,
|
||||||
@ -10,7 +8,7 @@ CREATE TABLE manga_sync(
|
|||||||
last_chapter_read REAL NOT NULL,
|
last_chapter_read REAL NOT NULL,
|
||||||
total_chapters INTEGER NOT NULL,
|
total_chapters INTEGER NOT NULL,
|
||||||
status INTEGER NOT NULL,
|
status INTEGER NOT NULL,
|
||||||
score REAL AS Float NOT NULL,
|
score REAL NOT NULL,
|
||||||
remote_url TEXT NOT NULL,
|
remote_url TEXT NOT NULL,
|
||||||
start_date INTEGER NOT NULL,
|
start_date INTEGER NOT NULL,
|
||||||
finish_date INTEGER NOT NULL,
|
finish_date INTEGER NOT NULL,
|
||||||
|
@ -11,7 +11,7 @@ data class Chapter(
|
|||||||
val url: String,
|
val url: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val dateUpload: Long,
|
val dateUpload: Long,
|
||||||
val chapterNumber: Float,
|
val chapterNumber: Double,
|
||||||
val scanlator: String?,
|
val scanlator: String?,
|
||||||
val lastModifiedAt: Long,
|
val lastModifiedAt: Long,
|
||||||
) {
|
) {
|
||||||
@ -30,7 +30,7 @@ data class Chapter(
|
|||||||
url = "",
|
url = "",
|
||||||
name = "",
|
name = "",
|
||||||
dateUpload = -1,
|
dateUpload = -1,
|
||||||
chapterNumber = -1f,
|
chapterNumber = -1.0,
|
||||||
scanlator = null,
|
scanlator = null,
|
||||||
lastModifiedAt = 0,
|
lastModifiedAt = 0,
|
||||||
)
|
)
|
||||||
|
@ -11,7 +11,7 @@ data class ChapterUpdate(
|
|||||||
val url: String? = null,
|
val url: String? = null,
|
||||||
val name: String? = null,
|
val name: String? = null,
|
||||||
val dateUpload: Long? = null,
|
val dateUpload: Long? = null,
|
||||||
val chapterNumber: Float? = null,
|
val chapterNumber: Double? = null,
|
||||||
val scanlator: String? = null,
|
val scanlator: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ object ChapterRecognition {
|
|||||||
*/
|
*/
|
||||||
private val unwantedWhiteSpace = Regex("""\s(?=extra|special|omake)""")
|
private val unwantedWhiteSpace = Regex("""\s(?=extra|special|omake)""")
|
||||||
|
|
||||||
fun parseChapterNumber(mangaTitle: String, chapterName: String, chapterNumber: Float? = null): Float {
|
fun parseChapterNumber(mangaTitle: String, chapterName: String, chapterNumber: Double? = null): Double {
|
||||||
// If chapter number is known return.
|
// If chapter number is known return.
|
||||||
if (chapterNumber != null && (chapterNumber == -2f || chapterNumber > -1f)) {
|
if (chapterNumber != null && (chapterNumber == -2.0 || chapterNumber > -1.0)) {
|
||||||
return chapterNumber
|
return chapterNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ object ChapterRecognition {
|
|||||||
// Take the first number encountered.
|
// Take the first number encountered.
|
||||||
number.find(name)?.let { return getChapterNumberFromMatch(it) }
|
number.find(name)?.let { return getChapterNumberFromMatch(it) }
|
||||||
|
|
||||||
return chapterNumber ?: -1f
|
return chapterNumber ?: -1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,9 +65,9 @@ object ChapterRecognition {
|
|||||||
* @param match result of regex
|
* @param match result of regex
|
||||||
* @return chapter number if found else null
|
* @return chapter number if found else null
|
||||||
*/
|
*/
|
||||||
private fun getChapterNumberFromMatch(match: MatchResult): Float {
|
private fun getChapterNumberFromMatch(match: MatchResult): Double {
|
||||||
return match.let {
|
return match.let {
|
||||||
val initial = it.groups[1]?.value?.toFloat()!!
|
val initial = it.groups[1]?.value?.toDouble()!!
|
||||||
val subChapterDecimal = it.groups[2]?.value
|
val subChapterDecimal = it.groups[2]?.value
|
||||||
val subChapterAlpha = it.groups[3]?.value
|
val subChapterAlpha = it.groups[3]?.value
|
||||||
val addition = checkForDecimal(subChapterDecimal, subChapterAlpha)
|
val addition = checkForDecimal(subChapterDecimal, subChapterAlpha)
|
||||||
|
@ -3,16 +3,16 @@ package tachiyomi.domain.chapter.service
|
|||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
fun List<Float>.missingChaptersCount(): Int {
|
fun List<Double>.missingChaptersCount(): Int {
|
||||||
if (this.isEmpty()) {
|
if (this.isEmpty()) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val chapters = this
|
val chapters = this
|
||||||
// Ignore unknown chapter numbers
|
// Ignore unknown chapter numbers
|
||||||
.filterNot { it == -1f }
|
.filterNot { it == -1.0 }
|
||||||
// Convert to integers, as we cannot check if 16.5 is missing
|
// Convert to integers, as we cannot check if 16.5 is missing
|
||||||
.map(Float::toInt)
|
.map(Double::toInt)
|
||||||
// Only keep unique chapters so that -1 or 16 are not counted multiple times
|
// Only keep unique chapters so that -1 or 16 are not counted multiple times
|
||||||
.distinct()
|
.distinct()
|
||||||
.sorted()
|
.sorted()
|
||||||
@ -43,7 +43,7 @@ fun calculateChapterGap(higherChapter: Chapter?, lowerChapter: Chapter?): Int {
|
|||||||
return calculateChapterGap(higherChapter.chapterNumber, lowerChapter.chapterNumber)
|
return calculateChapterGap(higherChapter.chapterNumber, lowerChapter.chapterNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun calculateChapterGap(higherChapterNumber: Float, lowerChapterNumber: Float): Int {
|
fun calculateChapterGap(higherChapterNumber: Double, lowerChapterNumber: Double): Int {
|
||||||
if (higherChapterNumber < 0f || lowerChapterNumber < 0f) return 0
|
if (higherChapterNumber < 0.0 || lowerChapterNumber < 0.0) return 0
|
||||||
return floor(higherChapterNumber).toInt() - floor(lowerChapterNumber).toInt() - 1
|
return floor(higherChapterNumber).toInt() - floor(lowerChapterNumber).toInt() - 1
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ data class HistoryWithRelations(
|
|||||||
val chapterId: Long,
|
val chapterId: Long,
|
||||||
val mangaId: Long,
|
val mangaId: Long,
|
||||||
val title: String,
|
val title: String,
|
||||||
val chapterNumber: Float,
|
val chapterNumber: Double,
|
||||||
val readAt: Date?,
|
val readAt: Date?,
|
||||||
val readDuration: Long,
|
val readDuration: Long,
|
||||||
val coverData: MangaCover,
|
val coverData: MangaCover,
|
||||||
|
@ -10,7 +10,7 @@ data class Track(
|
|||||||
val lastChapterRead: Double,
|
val lastChapterRead: Double,
|
||||||
val totalChapters: Long,
|
val totalChapters: Long,
|
||||||
val status: Long,
|
val status: Long,
|
||||||
val score: Float,
|
val score: Double,
|
||||||
val remoteUrl: String,
|
val remoteUrl: String,
|
||||||
val startDate: Long,
|
val startDate: Long,
|
||||||
val finishDate: Long,
|
val finishDate: Long,
|
||||||
|
@ -80,7 +80,6 @@ leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", versi
|
|||||||
sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
||||||
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions-jvm", version.ref = "sqldelight" }
|
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions-jvm", version.ref = "sqldelight" }
|
||||||
sqldelight-android-paging = { module = "app.cash.sqldelight:androidx-paging3-extensions", version.ref = "sqldelight" }
|
sqldelight-android-paging = { module = "app.cash.sqldelight:androidx-paging3-extensions", version.ref = "sqldelight" }
|
||||||
sqldelight-primitive-adapters = { module = "app.cash.sqldelight:primitive-adapters", version.ref = "sqldelight" }
|
|
||||||
sqldelight-dialects-sql = { module = "app.cash.sqldelight:sqlite-3-38-dialect", version.ref = "sqldelight" }
|
sqldelight-dialects-sql = { module = "app.cash.sqldelight:sqlite-3-38-dialect", version.ref = "sqldelight" }
|
||||||
sqldelight-gradle = { module = "app.cash.sqldelight:gradle-plugin", version.ref = "sqldelight" }
|
sqldelight-gradle = { module = "app.cash.sqldelight:gradle-plugin", version.ref = "sqldelight" }
|
||||||
|
|
||||||
@ -101,7 +100,7 @@ js-engine = ["quickjs-android"]
|
|||||||
sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"]
|
sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"]
|
||||||
coil = ["coil-core", "coil-gif", "coil-compose"]
|
coil = ["coil-core", "coil-gif", "coil-compose"]
|
||||||
shizuku = ["shizuku-api", "shizuku-provider"]
|
shizuku = ["shizuku-api", "shizuku-provider"]
|
||||||
sqldelight = ["sqldelight-android-driver", "sqldelight-coroutines", "sqldelight-android-paging", "sqldelight-primitive-adapters"]
|
sqldelight = ["sqldelight-android-driver", "sqldelight-coroutines", "sqldelight-android-paging"]
|
||||||
voyager = ["voyager-navigator", "voyager-tab-navigator", "voyager-transitions"]
|
voyager = ["voyager-navigator", "voyager-tab-navigator", "voyager-transitions"]
|
||||||
richtext = ["richtext-commonmark", "richtext-m3"]
|
richtext = ["richtext-commonmark", "richtext-m3"]
|
||||||
test = ["junit", "kotest-assertions", "mockk"]
|
test = ["junit", "kotest-assertions", "mockk"]
|
@ -264,7 +264,9 @@ actual class LocalSource(
|
|||||||
chapterFile.nameWithoutExtension
|
chapterFile.nameWithoutExtension
|
||||||
}
|
}
|
||||||
date_upload = chapterFile.lastModified()
|
date_upload = chapterFile.lastModified()
|
||||||
chapter_number = ChapterRecognition.parseChapterNumber(manga.title, this.name, this.chapter_number)
|
chapter_number = ChapterRecognition
|
||||||
|
.parseChapterNumber(manga.title, this.name, this.chapter_number.toDouble())
|
||||||
|
.toFloat()
|
||||||
|
|
||||||
val format = Format.valueOf(chapterFile)
|
val format = Format.valueOf(chapterFile)
|
||||||
if (format is Format.Epub) {
|
if (format is Format.Epub) {
|
||||||
|
Loading…
Reference in New Issue
Block a user