Last commit merged: c9a1bd86b5
This commit is contained in:
LuftVerbot 2023-11-18 17:20:36 +01:00
parent a2a445fdc5
commit eeddf17691
75 changed files with 35062 additions and 20360 deletions

View file

@ -73,11 +73,11 @@ android {
initWith(getByName("release"))
buildConfigField("boolean", "PREVIEW", "true")
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks.add("release")
val debugType = getByName("debug")
signingConfig = debugType.signingConfig
versionNameSuffix = debugType.versionNameSuffix
applicationIdSuffix = debugType.applicationIdSuffix
matchingFallbacks.add("release")
}
create("benchmark") {
initWith(getByName("release"))
@ -177,7 +177,6 @@ dependencies {
implementation(androidx.paging.compose)
implementation(libs.bundles.sqlite)
implementation(libs.sqldelight.primitive.adapters)
implementation(kotlinx.reflect)

File diff suppressed because it is too large Load diff

View file

@ -99,7 +99,7 @@ fun getComicInfo(manga: Manga, chapter: Chapter, chapterUrl: String, categories:
title = ComicInfo.Title(chapter.name),
series = ComicInfo.Series(manga.title),
number = chapter.chapterNumber.takeIf { it >= 0 }?.let {
if ((it.rem(1) == 0.0F)) {
if ((it.rem(1) == 0.0)) {
ComicInfo.Number(it.toInt().toString())
} else {
ComicInfo.Number(it.toString())

View file

@ -151,9 +151,9 @@ class SyncChaptersWithSource(
val reAdded = mutableListOf<Chapter>()
val deletedChapterNumbers = TreeSet<Float>()
val deletedReadChapterNumbers = TreeSet<Float>()
val deletedBookmarkedChapterNumbers = TreeSet<Float>()
val deletedChapterNumbers = TreeSet<Double>()
val deletedReadChapterNumbers = TreeSet<Double>()
val deletedBookmarkedChapterNumbers = TreeSet<Double>()
toDelete.forEach { chapter ->
if (chapter.read) deletedReadChapterNumbers.add(chapter.chapterNumber)

View file

@ -12,7 +12,7 @@ fun Chapter.toSChapter(): SChapter {
it.url = url
it.name = name
it.date_upload = dateUpload
it.chapter_number = chapterNumber
it.chapter_number = chapterNumber.toFloat()
it.scanlator = scanlator
}
}
@ -22,7 +22,7 @@ fun Chapter.copyFromSChapter(sChapter: SChapter): Chapter {
name = sChapter.name,
url = sChapter.url,
dateUpload = sChapter.date_upload,
chapterNumber = sChapter.chapter_number,
chapterNumber = sChapter.chapter_number.toDouble(),
scanlator = sChapter.scanlator?.ifBlank { null },
)
}
@ -48,6 +48,6 @@ fun Chapter.toDbChapter(): DbChapter = ChapterImpl().also {
it.last_page_read = lastPageRead.toInt()
it.date_fetch = dateFetch
it.date_upload = dateUpload
it.chapter_number = chapterNumber
it.chapter_number = chapterNumber.toFloat()
it.source_order = sourceOrder.toInt()
}

View file

@ -151,9 +151,9 @@ class SyncEpisodesWithSource(
val reAdded = mutableListOf<Episode>()
val deletedEpisodeNumbers = TreeSet<Float>()
val deletedSeenEpisodeNumbers = TreeSet<Float>()
val deletedBookmarkedEpisodeNumbers = TreeSet<Float>()
val deletedEpisodeNumbers = TreeSet<Double>()
val deletedSeenEpisodeNumbers = TreeSet<Double>()
val deletedBookmarkedEpisodeNumbers = TreeSet<Double>()
toDelete.forEach { episode ->
if (episode.seen) deletedSeenEpisodeNumbers.add(episode.episodeNumber)

View file

@ -12,7 +12,7 @@ fun Episode.toSEpisode(): SEpisode {
it.url = url
it.name = name
it.date_upload = dateUpload
it.episode_number = episodeNumber
it.episode_number = episodeNumber.toFloat()
it.scanlator = scanlator
}
}
@ -22,7 +22,7 @@ fun Episode.copyFromSEpisode(sEpisode: SEpisode): Episode {
name = sEpisode.name,
url = sEpisode.url,
dateUpload = sEpisode.date_upload,
episodeNumber = sEpisode.episode_number,
episodeNumber = sEpisode.episode_number.toDouble(),
scanlator = sEpisode.scanlator?.ifBlank { null },
)
}
@ -49,6 +49,6 @@ fun Episode.toDbEpisode(): DbEpisode = EpisodeImpl().also {
it.total_seconds = totalSeconds
it.date_fetch = dateFetch
it.date_upload = dateUpload
it.episode_number = episodeNumber
it.episode_number = episodeNumber.toFloat()
it.source_order = sourceOrder.toInt()
}

View file

@ -22,7 +22,7 @@ fun AnimeTrack.toDbTrack(): DbAnimeTrack = eu.kanade.tachiyomi.data.database.mod
it.last_episode_seen = lastEpisodeSeen.toFloat()
it.total_episodes = totalEpisodes.toInt()
it.status = status.toInt()
it.score = score
it.score = score.toFloat()
it.tracking_url = remoteUrl
it.started_watching_date = startDate
it.finished_watching_date = finishDate
@ -40,7 +40,7 @@ fun DbAnimeTrack.toDomainTrack(idRequired: Boolean = true): AnimeTrack? {
lastEpisodeSeen = last_episode_seen.toDouble(),
totalEpisodes = total_episodes.toLong(),
status = status.toLong(),
score = score,
score = score.toDouble(),
remoteUrl = tracking_url,
startDate = started_watching_date,
finishDate = finished_watching_date,

View file

@ -22,7 +22,7 @@ fun MangaTrack.toDbTrack(): DbMangaTrack = eu.kanade.tachiyomi.data.database.mod
it.last_chapter_read = lastChapterRead.toFloat()
it.total_chapters = totalChapters.toInt()
it.status = status.toInt()
it.score = score
it.score = score.toFloat()
it.tracking_url = remoteUrl
it.started_reading_date = startDate
it.finished_reading_date = finishDate
@ -40,7 +40,7 @@ fun DbMangaTrack.toDomainTrack(idRequired: Boolean = true): MangaTrack? {
lastChapterRead = last_chapter_read.toDouble(),
totalChapters = total_chapters.toLong(),
status = status.toLong(),
score = score,
score = score.toDouble(),
remoteUrl = tracking_url,
startDate = started_reading_date,
finishDate = finished_reading_date,

View file

@ -487,7 +487,7 @@ private fun AnimeScreenSmallImpl(
NextEpisodeAiringListItem(
title = stringResource(
R.string.display_mode_episode,
formatEpisodeNumber(state.airingEpisodeNumber.toFloat()),
formatEpisodeNumber(state.airingEpisodeNumber),
),
date = formatTime(state.airingTime, useDayFormat = true),
)
@ -747,7 +747,7 @@ fun AnimeScreenLargeImpl(
NextEpisodeAiringListItem(
title = stringResource(
R.string.display_mode_episode,
formatEpisodeNumber(state.airingEpisodeNumber.toFloat()),
formatEpisodeNumber(state.airingEpisodeNumber),
),
date = formatTime(state.airingTime, useDayFormat = true),
)

View file

@ -358,10 +358,10 @@ object SettingsLibraryScreen : SearchableSettings {
pluralStringResource(R.plurals.pref_update_release_following_days, followMangaRange, followMangaRange),
).joinToString(),
onClick = { showFetchMangaRangesDialog = true },
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateMangaRestriction && isDevFlavor },
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateMangaRestriction},
Preference.PreferenceItem.InfoPreference(
title = stringResource(R.string.pref_update_release_grace_period_info),
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateMangaRestriction && isDevFlavor },
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateMangaRestriction},
Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_update_anime_release_grace_period),
subtitle = listOf(
@ -369,10 +369,10 @@ object SettingsLibraryScreen : SearchableSettings {
pluralStringResource(R.plurals.pref_update_release_following_days, followAnimeRange, followAnimeRange),
).joinToString(),
onClick = { showFetchAnimeRangesDialog = true },
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateAnimeRestriction && isDevFlavor },
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateAnimeRestriction},
Preference.PreferenceItem.InfoPreference(
title = stringResource(R.string.pref_update_release_grace_period_info),
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateAnimeRestriction && isDevFlavor },
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateAnimeRestriction},
Preference.PreferenceItem.SwitchPreference(
pref = libraryPreferences.newShowUpdatesCount(),

View file

@ -15,6 +15,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat
@ -45,6 +46,7 @@ class OpenSourceLibraryLicenseScreen(
Text(
text = name,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
navigationIcon = {

View file

@ -28,9 +28,11 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.serialization.protobuf.schema.ProtoBufSchemaGenerator
import tachiyomi.presentation.core.components.material.Scaffold
object BackupSchemaScreen : Screen() {
class BackupSchemaScreen : Screen() {
const val title = "Backup file schema"
companion object {
const val title = "Backup file schema"
}
@Composable
override fun Content() {

View file

@ -18,7 +18,8 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.DeviceUtil
import kotlinx.coroutines.guava.await
object DebugInfoScreen : Screen() {
class DebugInfoScreen : Screen() {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
@ -29,11 +30,11 @@ object DebugInfoScreen : Screen() {
listOf(
Preference.PreferenceItem.TextPreference(
title = WorkerInfoScreen.title,
onClick = { navigator.push(WorkerInfoScreen) },
onClick = { navigator.push(WorkerInfoScreen()) },
),
Preference.PreferenceItem.TextPreference(
title = BackupSchemaScreen.title,
onClick = { navigator.push(BackupSchemaScreen) },
onClick = { navigator.push(BackupSchemaScreen()) },
),
getAppInfoGroup(),
getDeviceInfoGroup(),
@ -67,11 +68,15 @@ object DebugInfoScreen : Screen() {
@Composable
@ReadOnlyComposable
private fun getWebViewVersion(): String {
val webView = WebView.getCurrentWebViewPackage() ?: return "how did you get here?"
val pm = LocalContext.current.packageManager
val label = webView.applicationInfo.loadLabel(pm)
val version = webView.versionName
return "$label $version"
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val webView = WebView.getCurrentWebViewPackage() ?: return "how did you get here?"
val pm = LocalContext.current.packageManager
val label = webView.applicationInfo.loadLabel(pm)
val version = webView.versionName
return "$label $version"
} else {
return "Unknown"
}
}
@Composable

View file

@ -43,9 +43,11 @@ import kotlinx.coroutines.flow.stateIn
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.util.plus
object WorkerInfoScreen : Screen() {
class WorkerInfoScreen : Screen() {
const val title = "Worker info"
companion object {
const val title = "Worker info"
}
@Composable
override fun Content() {

View file

@ -87,7 +87,7 @@ fun AnimeTrackInfoDialogHome(
},
onEpisodesClick = { onEpisodeClick(item) },
score = item.service.animeService.displayScore(item.track.toDbTrack())
.takeIf { supportsScoring && item.track.score != 0F },
.takeIf { supportsScoring && item.track.score != 0.0 },
onScoreClick = { onScoreClick(item) }
.takeIf { supportsScoring },
startDate = remember(item.track.startDate) { dateFormat.format(item.track.startDate) }

View file

@ -98,7 +98,7 @@ fun MangaTrackInfoDialogHome(
},
onChaptersClick = { onChapterClick(item) },
score = item.service.mangaService.displayScore(item.track.toDbTrack())
.takeIf { supportsScoring && item.track.score != 0F },
.takeIf { supportsScoring && item.track.score != 0.0 },
onScoreClick = { onScoreClick(item) }
.takeIf { supportsScoring },
startDate = remember(item.track.startDate) { dateFormat.format(item.track.startDate) }

View file

@ -8,10 +8,10 @@ private val formatter = DecimalFormat(
DecimalFormatSymbols().apply { decimalSeparator = '.' },
)
fun formatChapterNumber(chapterNumber: Float): String {
fun formatChapterNumber(chapterNumber: Double): String {
return formatter.format(chapterNumber)
}
fun formatEpisodeNumber(episodeNumber: Float): String {
fun formatEpisodeNumber(episodeNumber: Double): String {
return formatter.format(episodeNumber)
}

View file

@ -5,16 +5,11 @@ import android.os.Build
import androidx.core.content.ContextCompat
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import app.cash.sqldelight.adapter.primitive.FloatColumnAdapter
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import data.Chapters
import data.History
import data.Manga_sync
import data.Mangas
import dataanime.Anime_sync
import dataanime.Animehistory
import dataanime.Animes
import dataanime.Episodes
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.track.anime.store.DelayedAnimeTrackingStore
@ -55,13 +50,13 @@ import tachiyomi.core.preference.PreferenceStore
import tachiyomi.core.provider.AndroidBackupFolderProvider
import tachiyomi.core.provider.AndroidDownloadFolderProvider
import tachiyomi.data.Database
import tachiyomi.data.dateAdapter
import tachiyomi.data.DateColumnAdapter
import tachiyomi.data.StringListColumnAdapter
import tachiyomi.data.UpdateStrategyColumnAdapter
import tachiyomi.data.handlers.anime.AndroidAnimeDatabaseHandler
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
import tachiyomi.data.handlers.manga.AndroidMangaDatabaseHandler
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
import tachiyomi.data.listOfStringsAdapter
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.library.service.LibraryPreferences
@ -136,18 +131,12 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory {
Database(
driver = sqlDriverManga,
chaptersAdapter = Chapters.Adapter(
chapter_numberAdapter = FloatColumnAdapter,
),
historyAdapter = History.Adapter(
last_readAdapter = dateAdapter,
),
manga_syncAdapter = Manga_sync.Adapter(
scoreAdapter = FloatColumnAdapter,
last_readAdapter = DateColumnAdapter,
),
mangasAdapter = Mangas.Adapter(
genreAdapter = listOfStringsAdapter,
update_strategyAdapter = updateStrategyAdapter,
genreAdapter = StringListColumnAdapter,
update_strategyAdapter = UpdateStrategyColumnAdapter,
),
)
}
@ -155,18 +144,12 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory {
AnimeDatabase(
driver = sqlDriverAnime,
episodesAdapter = Episodes.Adapter(
episode_numberAdapter = FloatColumnAdapter,
),
animehistoryAdapter = Animehistory.Adapter(
last_seenAdapter = dateAdapter,
),
anime_syncAdapter = Anime_sync.Adapter(
scoreAdapter = FloatColumnAdapter,
last_seenAdapter = DateColumnAdapter,
),
animesAdapter = Animes.Adapter(
genreAdapter = listOfStringsAdapter,
update_strategyAdapter = updateStrategyAdapter,
genreAdapter = StringListColumnAdapter,
update_strategyAdapter = UpdateStrategyColumnAdapter,
),
)
}

View file

@ -65,9 +65,9 @@ import okio.gzip
import okio.sink
import tachiyomi.core.util.lang.toLong
import tachiyomi.core.util.system.logcat
import tachiyomi.data.UpdateStrategyColumnAdapter
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.category.anime.interactor.GetAnimeCategories
import tachiyomi.domain.category.manga.interactor.GetMangaCategories
@ -778,7 +778,7 @@ class BackupManager(
track.last_chapter_read,
track.total_chapters,
track.status,
track.score.toDouble(),
track.score,
track.remote_url,
track.start_date,
track.finish_date,
@ -861,7 +861,7 @@ class BackupManager(
track.last_episode_seen,
track.total_episodes,
track.status,
track.score.toDouble(),
track.score,
track.remote_url,
track.start_date,
track.finish_date,
@ -1050,7 +1050,7 @@ class BackupManager(
coverLastModified = manga.coverLastModified,
dateAdded = manga.dateAdded,
mangaId = manga.id!!,
updateStrategy = manga.updateStrategy.let(updateStrategyAdapter::encode),
updateStrategy = manga.updateStrategy.let(UpdateStrategyColumnAdapter::encode),
)
}
return manga.id
@ -1078,7 +1078,7 @@ class BackupManager(
coverLastModified = anime.coverLastModified,
dateAdded = anime.dateAdded,
animeId = anime.id!!,
updateStrategy = anime.updateStrategy.let(updateStrategyAdapter::encode),
updateStrategy = anime.updateStrategy.let(UpdateStrategyColumnAdapter::encode),
)
}
return anime.id

View file

@ -43,7 +43,7 @@ data class BackupAnimeTracking(
title = this@BackupAnimeTracking.title,
lastEpisodeSeen = this@BackupAnimeTracking.lastEpisodeSeen.toDouble(),
totalEpisodes = this@BackupAnimeTracking.totalEpisodes.toLong(),
score = this@BackupAnimeTracking.score,
score = this@BackupAnimeTracking.score.toDouble(),
status = this@BackupAnimeTracking.status.toLong(),
startDate = this@BackupAnimeTracking.startedWatchingDate,
finishDate = this@BackupAnimeTracking.finishedWatchingDate,
@ -62,7 +62,7 @@ data class BackupAnimeTracking(
// convert to float for 1.x
lastEpisodeSeen = track.lastEpisodeSeen.toFloat(),
totalEpisodes = track.totalEpisodes.toInt(),
score = track.score,
score = track.score.toFloat(),
status = track.status.toInt(),
startedWatchingDate = track.startDate,
finishedWatchingDate = track.finishDate,
@ -72,7 +72,7 @@ data class BackupAnimeTracking(
}
}
val backupAnimeTrackMapper = { _id: Long, anime_id: Long, syncId: Long, mediaId: Long, libraryId: Long?, title: String, lastEpisodeSeen: Double, totalEpisodes: Long, status: Long, score: Float, remoteUrl: String, startDate: Long, finishDate: Long ->
val backupAnimeTrackMapper = { _id: Long, anime_id: Long, syncId: Long, mediaId: Long, libraryId: Long?, title: String, lastEpisodeSeen: Double, totalEpisodes: Long, status: Long, score: Double, remoteUrl: String, startDate: Long, finishDate: Long ->
BackupAnimeTracking(
syncId = syncId.toInt(),
mediaId = mediaId,
@ -81,7 +81,7 @@ val backupAnimeTrackMapper = { _id: Long, anime_id: Long, syncId: Long, mediaId:
title = title,
lastEpisodeSeen = lastEpisodeSeen.toFloat(),
totalEpisodes = totalEpisodes.toInt(),
score = score,
score = score.toFloat(),
status = status.toInt(),
startedWatchingDate = startDate,
finishedWatchingDate = finishDate,

View file

@ -26,7 +26,7 @@ data class BackupChapter(
return Chapter.create().copy(
url = this@BackupChapter.url,
name = this@BackupChapter.name,
chapterNumber = this@BackupChapter.chapterNumber,
chapterNumber = this@BackupChapter.chapterNumber.toDouble(),
scanlator = this@BackupChapter.scanlator,
read = this@BackupChapter.read,
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(
url = url,
name = name,
chapterNumber = chapterNumber,
chapterNumber = chapterNumber.toFloat(),
scanlator = scanlator,
read = read,
bookmark = bookmark,

View file

@ -27,7 +27,7 @@ data class BackupEpisode(
return Episode.create().copy(
url = this@BackupEpisode.url,
name = this@BackupEpisode.name,
episodeNumber = this@BackupEpisode.episodeNumber,
episodeNumber = this@BackupEpisode.episodeNumber.toDouble(),
scanlator = this@BackupEpisode.scanlator,
seen = this@BackupEpisode.seen,
bookmark = this@BackupEpisode.bookmark,
@ -41,11 +41,11 @@ data class BackupEpisode(
}
}
val backupEpisodeMapper = { _: Long, _: Long, url: String, name: String, scanlator: String?, seen: Boolean, bookmark: Boolean, lastSecondSeen: Long, totalSeconds: Long, episodeNumber: Float, source_order: Long, dateFetch: Long, dateUpload: Long, lastModifiedAt: Long ->
val backupEpisodeMapper = { _: Long, _: Long, url: String, name: String, scanlator: String?, seen: Boolean, bookmark: Boolean, lastSecondSeen: Long, totalSeconds: Long, episodeNumber: Double, source_order: Long, dateFetch: Long, dateUpload: Long, lastModifiedAt: Long ->
BackupEpisode(
url = url,
name = name,
episodeNumber = episodeNumber,
episodeNumber = episodeNumber.toFloat(),
scanlator = scanlator,
seen = seen,
bookmark = bookmark,

View file

@ -44,7 +44,7 @@ data class BackupTracking(
title = this@BackupTracking.title,
lastChapterRead = this@BackupTracking.lastChapterRead.toDouble(),
totalChapters = this@BackupTracking.totalChapters.toLong(),
score = this@BackupTracking.score,
score = this@BackupTracking.score.toDouble(),
status = this@BackupTracking.status.toLong(),
startDate = this@BackupTracking.startedReadingDate,
finishDate = this@BackupTracking.finishedReadingDate,
@ -54,7 +54,7 @@ data class BackupTracking(
}
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(
syncId = syncId.toInt(),
mediaId = mediaId,
@ -63,7 +63,7 @@ val backupTrackMapper = {
title = title,
lastChapterRead = lastChapterRead.toFloat(),
totalChapters = totalChapters.toInt(),
score = score,
score = score.toFloat(),
status = status.toInt(),
startedReadingDate = startDate,
finishedReadingDate = finishDate,

View file

@ -39,7 +39,7 @@ fun Episode.toDomainEpisode(): DomainEpisode? {
url = url,
name = name,
dateUpload = date_upload,
episodeNumber = episode_number,
episodeNumber = episode_number.toDouble(),
scanlator = scanlator,
lastModifiedAt = last_modified,
)

View file

@ -36,7 +36,7 @@ fun Chapter.toDomainChapter(): DomainChapter? {
url = url,
name = name,
dateUpload = date_upload,
chapterNumber = chapter_number,
chapterNumber = chapter_number.toDouble(),
scanlator = scanlator,
lastModifiedAt = last_modified,
)

View file

@ -39,7 +39,7 @@ interface AnimeTrackService {
fun getRewatchingStatus(): Int
// TODO: Store all scores as 10 point in the future maybe?
fun get10PointScore(track: DomainAnimeTrack): Float {
fun get10PointScore(track: DomainAnimeTrack): Double {
return track.score
}

View file

@ -39,7 +39,7 @@ interface MangaTrackService {
fun getRereadingStatus(): Int
// TODO: Store all scores as 10 point in the future maybe?
fun get10PointScore(track: DomainTrack): Float {
fun get10PointScore(track: DomainTrack): Double {
return track.score
}

View file

@ -114,14 +114,14 @@ class Anilist(id: Long) : TrackService(id), MangaTrackService, AnimeTrackService
}
}
override fun get10PointScore(track: DomainTrack): Float {
override fun get10PointScore(track: DomainTrack): Double {
// Score is stored in 100 point format
return track.score / 10f
return track.score / 10.0
}
override fun get10PointScore(track: DomainAnimeTrack): Float {
override fun get10PointScore(track: DomainAnimeTrack): Double {
// Score is stored in 100 point format
return track.score / 10f
return track.score / 10.0
}
override fun indexToScore(index: Int): Float {

View file

@ -238,10 +238,10 @@ class AnimeExtensionManager(
/**
* Uninstalls the anime extension that matches the given package name.
*
* @param pkgName The package name of the application to uninstall.
* @param extension The extension to uninstall.
*/
fun uninstallExtension(pkgName: String) {
installer.uninstallApk(pkgName)
fun uninstallExtension(extension: AnimeExtension) {
installer.uninstallApk(extension.pkgName)
}
/**
@ -260,18 +260,13 @@ class AnimeExtensionManager(
val nowTrustedAnimeExtensions = _untrustedAnimeExtensionsFlow.value.filter { it.signatureHash == signature }
_untrustedAnimeExtensionsFlow.value -= nowTrustedAnimeExtensions
val ctx = context
launchNow {
nowTrustedAnimeExtensions
.map { animeextension ->
async { AnimeExtensionLoader.loadExtensionFromPkgName(ctx, animeextension.pkgName) }
}
.map { it.await() }
.forEach { result ->
if (result is AnimeLoadResult.Success) {
registerNewExtension(result.extension)
}
async { AnimeExtensionLoader.loadExtensionFromPkgName(context, animeextension.pkgName) }.await()
}
.filterIsInstance<AnimeLoadResult.Success>()
.forEach { registerNewExtension(it.extension) }
}
}

View file

@ -238,10 +238,10 @@ class MangaExtensionManager(
/**
* Uninstalls the extension that matches the given package name.
*
* @param pkgName The package name of the application to uninstall.
* @param extension The extension to uninstall.
*/
fun uninstallExtension(pkgName: String) {
installer.uninstallApk(pkgName)
fun uninstallExtension(extension: MangaExtension) {
installer.uninstallApk(extension.pkgName)
}
/**
@ -260,18 +260,13 @@ class MangaExtensionManager(
val nowTrustedExtensions = _untrustedExtensionsFlow.value.filter { it.signatureHash == signature }
_untrustedExtensionsFlow.value -= nowTrustedExtensions
val ctx = context
launchNow {
nowTrustedExtensions
.map { extension ->
async { MangaExtensionLoader.loadMangaExtensionFromPkgName(ctx, extension.pkgName) }
}
.map { it.await() }
.forEach { result ->
if (result is MangaLoadResult.Success) {
registerNewExtension(result.extension)
}
async { MangaExtensionLoader.loadMangaExtensionFromPkgName(context, extension.pkgName) }.await()
}
.filterIsInstance<MangaLoadResult.Success>()
.forEach { registerNewExtension(it.extension) }
}
}

View file

@ -7,6 +7,6 @@ fun SEpisode.copyFrom(other: Episodes) {
name = other.name
url = other.url
date_upload = other.date_upload
episode_number = other.episode_number
episode_number = other.episode_number.toFloat()
scanlator = other.scanlator
}

View file

@ -7,6 +7,6 @@ fun SChapter.copyFrom(other: Chapters) {
name = other.name
url = other.url
date_upload = other.date_upload
chapter_number = other.chapter_number
chapter_number = other.chapter_number.toFloat()
scanlator = other.scanlator
}

View file

@ -171,8 +171,8 @@ class AnimeExtensionsScreenModel(
.onCompletion { removeDownloadState(extension) }
.collect()
fun uninstallExtension(pkgName: String) {
extensionManager.uninstallExtension(pkgName)
fun uninstallExtension(extension: AnimeExtension) {
extensionManager.uninstallExtension(extension)
}
fun findAvailableExtensions() {

View file

@ -41,7 +41,7 @@ fun animeExtensionsTab(
onLongClickItem = { extension ->
when (extension) {
is AnimeExtension.Available -> extensionsScreenModel.installExtension(extension)
else -> extensionsScreenModel.uninstallExtension(extension.pkgName)
else -> extensionsScreenModel.uninstallExtension(extension)
}
},
onClickItemCancel = extensionsScreenModel::cancelInstallUpdateExtension,
@ -49,7 +49,7 @@ fun animeExtensionsTab(
onInstallExtension = extensionsScreenModel::installExtension,
onOpenExtension = { navigator.push(AnimeExtensionDetailsScreen(it.pkgName)) },
onTrustExtension = { extensionsScreenModel.trustSignature(it.signatureHash) },
onUninstallExtension = { extensionsScreenModel.uninstallExtension(it.pkgName) },
onUninstallExtension = { extensionsScreenModel.uninstallExtension(it) },
onUpdateExtension = extensionsScreenModel::updateExtension,
onRefresh = extensionsScreenModel::findAvailableExtensions,
)

View file

@ -132,7 +132,7 @@ class AnimeExtensionDetailsScreenModel(
fun uninstallExtension() {
val extension = state.value.extension ?: return
extensionManager.uninstallExtension(extension.pkgName)
extensionManager.uninstallExtension(extension)
}
fun toggleSource(sourceId: Long) {

View file

@ -172,8 +172,8 @@ class MangaExtensionsScreenModel(
.onCompletion { removeDownloadState(extension) }
.collect()
fun uninstallExtension(pkgName: String) {
extensionManager.uninstallExtension(pkgName)
fun uninstallExtension(extension: MangaExtension) {
extensionManager.uninstallExtension(extension)
}
fun findAvailableExtensions() {

View file

@ -41,7 +41,7 @@ fun mangaExtensionsTab(
onLongClickItem = { extension ->
when (extension) {
is MangaExtension.Available -> extensionsScreenModel.installExtension(extension)
else -> extensionsScreenModel.uninstallExtension(extension.pkgName)
else -> extensionsScreenModel.uninstallExtension(extension)
}
},
onClickItemCancel = extensionsScreenModel::cancelInstallUpdateExtension,
@ -49,7 +49,7 @@ fun mangaExtensionsTab(
onInstallExtension = extensionsScreenModel::installExtension,
onOpenExtension = { navigator.push(MangaExtensionDetailsScreen(it.pkgName)) },
onTrustExtension = { extensionsScreenModel.trustSignature(it.signatureHash) },
onUninstallExtension = { extensionsScreenModel.uninstallExtension(it.pkgName) },
onUninstallExtension = { extensionsScreenModel.uninstallExtension(it) },
onUpdateExtension = extensionsScreenModel::updateExtension,
onRefresh = extensionsScreenModel::findAvailableExtensions,
)

View file

@ -132,7 +132,7 @@ class MangaExtensionDetailsScreenModel(
fun uninstallExtension() {
val extension = state.value.extension ?: return
extensionManager.uninstallExtension(extension.pkgName)
extensionManager.uninstallExtension(extension)
}
fun toggleSource(sourceId: Long) {

View file

@ -83,7 +83,7 @@ fun EpisodeListDialog(
val title = if (displayMode == Anime.EPISODE_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_episode,
formatEpisodeNumber(episode.episode_number),
formatEpisodeNumber(episode.episode_number.toDouble()),
)
} else {
episode.name

View file

@ -153,15 +153,13 @@ class AnimeStatsScreenModel(
private fun getTrackMeanScore(scoredAnimeTrackMap: Map<Long, List<AnimeTrack>>): Double {
return scoredAnimeTrackMap
.map { (_, tracks) ->
tracks.map {
get10PointScore(it)
}.average()
tracks.map(::get10PointScore).average()
}
.fastFilter { !it.isNaN() }
.average()
}
private fun get10PointScore(track: AnimeTrack): Float {
private fun get10PointScore(track: AnimeTrack): Double {
val service = trackManager.getService(track.syncId)!!
return service.animeService.get10PointScore(track)
}

View file

@ -138,15 +138,13 @@ class MangaStatsScreenModel(
private fun getTrackMeanScore(scoredMangaTrackMap: Map<Long, List<MangaTrack>>): Double {
return scoredMangaTrackMap
.map { (_, tracks) ->
tracks.map {
get10PointScore(it)
}.average()
tracks.map(::get10PointScore).average()
}
.fastFilter { !it.isNaN() }
.average()
}
private fun get10PointScore(track: MangaTrack): Float {
private fun get10PointScore(track: MangaTrack): Double {
val service = trackManager.getService(track.syncId)!!
return service.mangaService.get10PointScore(track)
}

View file

@ -4,23 +4,23 @@ import app.cash.sqldelight.ColumnAdapter
import eu.kanade.tachiyomi.source.model.UpdateStrategy
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 encode(value: Date): Long = value.time
}
private const val listOfStringsSeparator = ", "
val listOfStringsAdapter = object : ColumnAdapter<List<String>, String> {
private const val LIST_OF_STRINGS_SEPARATOR = ", "
object StringListColumnAdapter : ColumnAdapter<List<String>, String> {
override fun decode(databaseValue: String) =
if (databaseValue.isEmpty()) {
emptyList()
} 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 =
UpdateStrategy.entries.getOrElse(databaseValue.toInt()) { UpdateStrategy.ALWAYS_UPDATE }

View file

@ -4,9 +4,9 @@ import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
import tachiyomi.core.util.lang.toLong
import tachiyomi.core.util.system.logcat
import tachiyomi.data.StringListColumnAdapter
import tachiyomi.data.UpdateStrategyColumnAdapter
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
import tachiyomi.data.listOfStringsAdapter
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.entries.anime.model.Anime
import tachiyomi.domain.entries.anime.model.AnimeUpdate
import tachiyomi.domain.entries.anime.repository.AnimeRepository
@ -129,7 +129,7 @@ class AnimeRepositoryImpl(
artist = value.artist,
author = value.author,
description = value.description,
genre = value.genre?.let(listOfStringsAdapter::encode),
genre = value.genre?.let(StringListColumnAdapter::encode),
title = value.title,
status = value.status,
thumbnailUrl = value.thumbnailUrl,
@ -143,7 +143,7 @@ class AnimeRepositoryImpl(
coverLastModified = value.coverLastModified,
dateAdded = value.dateAdded,
animeId = value.id,
updateStrategy = value.updateStrategy?.let(updateStrategyAdapter::encode),
updateStrategy = value.updateStrategy?.let(UpdateStrategyColumnAdapter::encode),
)
}
}

View file

@ -4,9 +4,9 @@ import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
import tachiyomi.core.util.lang.toLong
import tachiyomi.core.util.system.logcat
import tachiyomi.data.StringListColumnAdapter
import tachiyomi.data.UpdateStrategyColumnAdapter
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
import tachiyomi.data.listOfStringsAdapter
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.entries.manga.model.Manga
import tachiyomi.domain.entries.manga.model.MangaUpdate
import tachiyomi.domain.entries.manga.repository.MangaRepository
@ -129,7 +129,7 @@ class MangaRepositoryImpl(
artist = value.artist,
author = value.author,
description = value.description,
genre = value.genre?.let(listOfStringsAdapter::encode),
genre = value.genre?.let(StringListColumnAdapter::encode),
title = value.title,
status = value.status,
thumbnailUrl = value.thumbnailUrl,
@ -143,7 +143,7 @@ class MangaRepositoryImpl(
coverLastModified = value.coverLastModified,
dateAdded = value.dateAdded,
mangaId = value.id,
updateStrategy = value.updateStrategy?.let(updateStrategyAdapter::encode),
updateStrategy = value.updateStrategy?.let(UpdateStrategyColumnAdapter::encode),
)
}
}

View file

@ -13,7 +13,7 @@ val animeHistoryMapper: (Long, Long, Date?) -> AnimeHistory = { id, episodeId, s
)
}
val animeHistoryWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Float, Date?) -> AnimeHistoryWithRelations = {
val animeHistoryWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Double, Date?) -> AnimeHistoryWithRelations = {
historyId, animeId, episodeId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, episodeNumber, seenAt ->
AnimeHistoryWithRelations(
id = historyId,

View file

@ -14,7 +14,7 @@ val mangaHistoryMapper: (Long, Long, Date?, Long) -> MangaHistory = { id, chapte
)
}
val mangaHistoryWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Float, Date?, Long) -> MangaHistoryWithRelations = {
val mangaHistoryWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Double, Date?, Long) -> MangaHistoryWithRelations = {
historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
MangaHistoryWithRelations(
id = historyId,

View file

@ -2,7 +2,7 @@ package tachiyomi.data.items.chapter
import tachiyomi.domain.items.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 ->
Chapter(
id = id,

View file

@ -2,7 +2,7 @@ package tachiyomi.data.items.episode
import tachiyomi.domain.items.episode.model.Episode
val episodeMapper: (Long, Long, String, String, String?, Boolean, Boolean, Long, Long, Float, Long, Long, Long, Long) -> Episode =
val episodeMapper: (Long, Long, String, String, String?, Boolean, Boolean, Long, Long, Double, Long, Long, Long, Long) -> Episode =
{ id, animeId, url, name, scanlator, seen, bookmark, lastSecondSeen, totalSeconds, episodeNumber, sourceOrder, dateFetch, dateUpload, lastModifiedAt ->
Episode(
id = id,

View file

@ -2,7 +2,7 @@ package tachiyomi.data.track.anime
import tachiyomi.domain.track.anime.model.AnimeTrack
val animeTrackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Float, String, Long, Long) -> AnimeTrack =
val animeTrackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Double, String, Long, Long) -> AnimeTrack =
{ id, animeId, syncId, remoteId, libraryId, title, lastEpisodeSeen, totalEpisodes, status, score, remoteUrl, startDate, finishDate ->
AnimeTrack(
id = id,

View file

@ -2,7 +2,7 @@ package tachiyomi.data.track.manga
import tachiyomi.domain.track.manga.model.MangaTrack
val mangaTrackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Float, String, Long, Long) -> MangaTrack =
val mangaTrackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Double, String, Long, Long) -> MangaTrack =
{ id, mangaId, syncId, remoteId, libraryId, title, lastChapterRead, totalChapters, status, score, remoteUrl, startDate, finishDate ->
MangaTrack(
id = id,

View file

@ -1,5 +1,4 @@
import kotlin.Boolean;
import kotlin.Float;
CREATE TABLE chapters(
_id INTEGER NOT NULL PRIMARY KEY,
@ -10,7 +9,7 @@ CREATE TABLE chapters(
read INTEGER AS Boolean NOT NULL,
bookmark INTEGER AS Boolean 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,
date_fetch INTEGER NOT NULL,
date_upload INTEGER NOT NULL,

View file

@ -1,5 +1,3 @@
import kotlin.Float;
CREATE TABLE manga_sync(
_id INTEGER NOT NULL PRIMARY KEY,
manga_id INTEGER NOT NULL,
@ -10,7 +8,7 @@ CREATE TABLE manga_sync(
last_chapter_read REAL NOT NULL,
total_chapters INTEGER NOT NULL,
status INTEGER NOT NULL,
score REAL AS Float NOT NULL,
score REAL NOT NULL,
remote_url TEXT NOT NULL,
start_date INTEGER NOT NULL,
finish_date INTEGER NOT NULL,

View file

@ -1,5 +1,3 @@
import kotlin.Float;
CREATE TABLE anime_sync(
_id INTEGER NOT NULL PRIMARY KEY,
anime_id INTEGER NOT NULL,
@ -10,7 +8,7 @@ CREATE TABLE anime_sync(
last_episode_seen REAL NOT NULL,
total_episodes INTEGER NOT NULL,
status INTEGER NOT NULL,
score REAL AS Float NOT NULL,
score REAL NOT NULL,
remote_url TEXT NOT NULL,
start_date INTEGER NOT NULL,
finish_date INTEGER NOT NULL,

View file

@ -1,5 +1,4 @@
import kotlin.Boolean;
import kotlin.Float;
CREATE TABLE episodes(
_id INTEGER NOT NULL PRIMARY KEY,
@ -11,7 +10,7 @@ CREATE TABLE episodes(
bookmark INTEGER AS Boolean NOT NULL,
last_second_seen INTEGER NOT NULL,
total_seconds INTEGER NOT NULL,
episode_number REAL AS Float NOT NULL,
episode_number REAL NOT NULL,
source_order INTEGER NOT NULL,
date_fetch INTEGER NOT NULL,
date_upload INTEGER NOT NULL,

View file

@ -8,7 +8,7 @@ data class AnimeHistoryWithRelations(
val episodeId: Long,
val animeId: Long,
val title: String,
val episodeNumber: Float,
val episodeNumber: Double,
val seenAt: Date?,
val coverData: AnimeCover,
)

View file

@ -8,7 +8,7 @@ data class MangaHistoryWithRelations(
val chapterId: Long,
val mangaId: Long,
val title: String,
val chapterNumber: Float,
val chapterNumber: Double,
val readAt: Date?,
val readDuration: Long,
val coverData: MangaCover,

View file

@ -11,7 +11,7 @@ data class Chapter(
val url: String,
val name: String,
val dateUpload: Long,
val chapterNumber: Float,
val chapterNumber: Double,
val scanlator: String?,
val lastModifiedAt: Long,
) {
@ -30,7 +30,7 @@ data class Chapter(
url = "",
name = "",
dateUpload = -1,
chapterNumber = -1f,
chapterNumber = -1.0,
scanlator = null,
lastModifiedAt = 0,
)

View file

@ -11,7 +11,7 @@ data class ChapterUpdate(
val url: String? = null,
val name: String? = null,
val dateUpload: Long? = null,
val chapterNumber: Float? = null,
val chapterNumber: Double? = null,
val scanlator: String? = null,
)

View file

@ -30,9 +30,9 @@ object ChapterRecognition {
*/
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 (chapterNumber != null && (chapterNumber == -2f || chapterNumber > -1f)) {
if (chapterNumber != null && (chapterNumber == -2.0 || chapterNumber > -1.0)) {
return chapterNumber
}
@ -57,7 +57,7 @@ object ChapterRecognition {
// Take the first number encountered.
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
* @return chapter number if found else null
*/
private fun getChapterNumberFromMatch(match: MatchResult): Float {
private fun getChapterNumberFromMatch(match: MatchResult): Double {
return match.let {
val initial = it.groups[1]?.value?.toFloat()!!
val initial = it.groups[1]?.value?.toDouble()!!
val subChapterDecimal = it.groups[2]?.value
val subChapterAlpha = it.groups[3]?.value
val addition = checkForDecimal(subChapterDecimal, subChapterAlpha)
@ -81,22 +81,22 @@ object ChapterRecognition {
* @param alpha alpha value of regex
* @return decimal/alpha float value
*/
private fun checkForDecimal(decimal: String?, alpha: String?): Float {
private fun checkForDecimal(decimal: String?, alpha: String?): Double {
if (!decimal.isNullOrEmpty()) {
return decimal.toFloat()
return decimal.toDouble()
}
if (!alpha.isNullOrEmpty()) {
if (alpha.contains("extra")) {
return .99f
return 0.99
}
if (alpha.contains("omake")) {
return .98f
return 0.98
}
if (alpha.contains("special")) {
return .97f
return 0.97
}
val trimmedAlpha = alpha.trimStart('.')
@ -105,15 +105,15 @@ object ChapterRecognition {
}
}
return .0f
return 0.0
}
/**
* x.a -> x.1, x.b -> x.2, etc
*/
private fun parseAlphaPostFix(alpha: Char): Float {
private fun parseAlphaPostFix(alpha: Char): Double {
val number = alpha.code - ('a'.code - 1)
if (number >= 10) return 0f
return number / 10f
if (number >= 10) return 0.0
return number / 10.0
}
}

View file

@ -12,7 +12,7 @@ data class Episode(
val url: String,
val name: String,
val dateUpload: Long,
val episodeNumber: Float,
val episodeNumber: Double,
val scanlator: String?,
val lastModifiedAt: Long,
) {
@ -32,7 +32,7 @@ data class Episode(
url = "",
name = "",
dateUpload = -1,
episodeNumber = -1f,
episodeNumber = -1.0,
scanlator = null,
lastModifiedAt = 0,
)

View file

@ -12,7 +12,7 @@ data class EpisodeUpdate(
val url: String? = null,
val name: String? = null,
val dateUpload: Long? = null,
val episodeNumber: Float? = null,
val episodeNumber: Double? = null,
val scanlator: String? = null,
)

View file

@ -30,9 +30,9 @@ object EpisodeRecognition {
*/
private val unwantedWhiteSpace = Regex("""\s(?=extra|special|omake)""")
fun parseEpisodeNumber(animeTitle: String, episodeName: String, episodeNumber: Float? = null): Float {
fun parseEpisodeNumber(animeTitle: String, episodeName: String, episodeNumber: Double? = null): Double {
// If episode number is known return.
if (episodeNumber != null && (episodeNumber == -2f || episodeNumber > -1f)) {
if (episodeNumber != null && (episodeNumber == -2.0 || episodeNumber > -1.0)) {
return episodeNumber
}
@ -57,7 +57,7 @@ object EpisodeRecognition {
// Take the first number encountered.
number.find(name)?.let { return getEpisodeNumberFromMatch(it) }
return episodeNumber ?: -1f
return episodeNumber ?: -1.0
}
/**
@ -65,9 +65,9 @@ object EpisodeRecognition {
* @param match result of regex
* @return chapter number if found else null
*/
private fun getEpisodeNumberFromMatch(match: MatchResult): Float {
private fun getEpisodeNumberFromMatch(match: MatchResult): Double {
return match.let {
val initial = it.groups[1]?.value?.toFloat()!!
val initial = it.groups[1]?.value?.toDouble()!!
val subChapterDecimal = it.groups[2]?.value
val subChapterAlpha = it.groups[3]?.value
val addition = checkForDecimal(subChapterDecimal, subChapterAlpha)
@ -81,22 +81,22 @@ object EpisodeRecognition {
* @param alpha alpha value of regex
* @return decimal/alpha float value
*/
private fun checkForDecimal(decimal: String?, alpha: String?): Float {
private fun checkForDecimal(decimal: String?, alpha: String?): Double {
if (!decimal.isNullOrEmpty()) {
return decimal.toFloat()
return decimal.toDouble()
}
if (!alpha.isNullOrEmpty()) {
if (alpha.contains("extra")) {
return .99f
return 0.99
}
if (alpha.contains("omake")) {
return .98f
return 0.98
}
if (alpha.contains("special")) {
return .97f
return 0.97
}
val trimmedAlpha = alpha.trimStart('.')
@ -105,15 +105,15 @@ object EpisodeRecognition {
}
}
return .0f
return 0.0
}
/**
* x.a -> x.1, x.b -> x.2, etc
*/
private fun parseAlphaPostFix(alpha: Char): Float {
private fun parseAlphaPostFix(alpha: Char): Double {
val number = alpha.code - ('a'.code - 1)
if (number >= 10) return 0f
return number / 10f
if (number >= 10) return 0.0
return number / 10.0
}
}

View file

@ -4,16 +4,16 @@ import tachiyomi.domain.items.chapter.model.Chapter
import tachiyomi.domain.items.episode.model.Episode
import kotlin.math.floor
fun List<Float>.missingItemsCount(): Int {
fun List<Double>.missingItemsCount(): Int {
if (this.isEmpty()) {
return 0
}
val items = this
// Ignore unknown item numbers
.filter { it != -1f }
.filter { it != -1.0 }
// 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
.distinct()
.sorted()
@ -44,8 +44,8 @@ fun calculateChapterGap(higherChapter: Chapter?, lowerChapter: Chapter?): Int {
return calculateChapterGap(higherChapter.chapterNumber, lowerChapter.chapterNumber)
}
fun calculateChapterGap(higherChapterNumber: Float, lowerChapterNumber: Float): Int {
if (higherChapterNumber < 0f || lowerChapterNumber < 0f) return 0
fun calculateChapterGap(higherChapterNumber: Double, lowerChapterNumber: Double): Int {
if (higherChapterNumber < 0.0 || lowerChapterNumber < 0.0) return 0
return floor(higherChapterNumber).toInt() - floor(lowerChapterNumber).toInt() - 1
}
@ -55,7 +55,7 @@ fun calculateEpisodeGap(higherEpisode: Episode?, lowerEpisode: Episode?): Int {
return calculateChapterGap(higherEpisode.episodeNumber, lowerEpisode.episodeNumber)
}
fun calculateEpisodeGap(higherEpisodeNumber: Float, lowerEpisodeNumber: Float): Int {
if (higherEpisodeNumber < 0f || lowerEpisodeNumber < 0f) return 0
fun calculateEpisodeGap(higherEpisodeNumber: Double, lowerEpisodeNumber: Double): Int {
if (higherEpisodeNumber < 0.0 || lowerEpisodeNumber < 0.0) return 0
return floor(higherEpisodeNumber).toInt() - floor(lowerEpisodeNumber).toInt() - 1
}

View file

@ -10,7 +10,7 @@ data class AnimeTrack(
val lastEpisodeSeen: Double,
val totalEpisodes: Long,
val status: Long,
val score: Float,
val score: Double,
val remoteUrl: String,
val startDate: Long,
val finishDate: Long,

View file

@ -10,7 +10,7 @@ data class MangaTrack(
val lastChapterRead: Double,
val totalChapters: Long,
val status: Long,
val score: Float,
val score: Double,
val remoteUrl: String,
val startDate: Long,
val finishDate: Long,

View file

@ -12,152 +12,152 @@ class ChapterRecognitionTest {
fun `Basic Ch prefix`() {
val mangaTitle = "Mokushiroku Alice"
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4: Misrepresentation", 4f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4: Misrepresentation", 4.0)
}
@Test
fun `Basic Ch prefix with space after period`() {
val mangaTitle = "Mokushiroku Alice"
assertChapter(mangaTitle, "Mokushiroku Alice Vol. 1 Ch. 4: Misrepresentation", 4f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol. 1 Ch. 4: Misrepresentation", 4.0)
}
@Test
fun `Basic Ch prefix with decimal`() {
val mangaTitle = "Mokushiroku Alice"
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.1: Misrepresentation", 4.1f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.4: Misrepresentation", 4.4f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.1: Misrepresentation", 4.1)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.4: Misrepresentation", 4.4)
}
@Test
fun `Basic Ch prefix with alpha postfix`() {
val mangaTitle = "Mokushiroku Alice"
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.a: Misrepresentation", 4.1f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.b: Misrepresentation", 4.2f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.extra: Misrepresentation", 4.99f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.a: Misrepresentation", 4.1)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.b: Misrepresentation", 4.2)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch.4.extra: Misrepresentation", 4.99)
}
@Test
fun `Name containing one number`() {
val mangaTitle = "Bleach"
assertChapter(mangaTitle, "Bleach 567 Down With Snowwhite", 567f)
assertChapter(mangaTitle, "Bleach 567 Down With Snowwhite", 567.0)
}
@Test
fun `Name containing one number and decimal`() {
val mangaTitle = "Bleach"
assertChapter(mangaTitle, "Bleach 567.1 Down With Snowwhite", 567.1f)
assertChapter(mangaTitle, "Bleach 567.4 Down With Snowwhite", 567.4f)
assertChapter(mangaTitle, "Bleach 567.1 Down With Snowwhite", 567.1)
assertChapter(mangaTitle, "Bleach 567.4 Down With Snowwhite", 567.4)
}
@Test
fun `Name containing one number and alpha`() {
val mangaTitle = "Bleach"
assertChapter(mangaTitle, "Bleach 567.a Down With Snowwhite", 567.1f)
assertChapter(mangaTitle, "Bleach 567.b Down With Snowwhite", 567.2f)
assertChapter(mangaTitle, "Bleach 567.extra Down With Snowwhite", 567.99f)
assertChapter(mangaTitle, "Bleach 567.a Down With Snowwhite", 567.1)
assertChapter(mangaTitle, "Bleach 567.b Down With Snowwhite", 567.2)
assertChapter(mangaTitle, "Bleach 567.extra Down With Snowwhite", 567.99)
}
@Test
fun `Chapter containing manga title and number`() {
val mangaTitle = "Solanin"
assertChapter(mangaTitle, "Solanin 028 Vol. 2", 28f)
assertChapter(mangaTitle, "Solanin 028 Vol. 2", 28.0)
}
@Test
fun `Chapter containing manga title and number decimal`() {
val mangaTitle = "Solanin"
assertChapter(mangaTitle, "Solanin 028.1 Vol. 2", 28.1f)
assertChapter(mangaTitle, "Solanin 028.4 Vol. 2", 28.4f)
assertChapter(mangaTitle, "Solanin 028.1 Vol. 2", 28.1)
assertChapter(mangaTitle, "Solanin 028.4 Vol. 2", 28.4)
}
@Test
fun `Chapter containing manga title and number alpha`() {
val mangaTitle = "Solanin"
assertChapter(mangaTitle, "Solanin 028.a Vol. 2", 28.1f)
assertChapter(mangaTitle, "Solanin 028.b Vol. 2", 28.2f)
assertChapter(mangaTitle, "Solanin 028.extra Vol. 2", 28.99f)
assertChapter(mangaTitle, "Solanin 028.a Vol. 2", 28.1)
assertChapter(mangaTitle, "Solanin 028.b Vol. 2", 28.2)
assertChapter(mangaTitle, "Solanin 028.extra Vol. 2", 28.99)
}
@Test
fun `Extreme case`() {
val mangaTitle = "Onepunch-Man"
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028", 28f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028", 28.0)
}
@Test
fun `Extreme case with decimal`() {
val mangaTitle = "Onepunch-Man"
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.1", 28.1f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.4", 28.4f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.1", 28.1)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.4", 28.4)
}
@Test
fun `Extreme case with alpha`() {
val mangaTitle = "Onepunch-Man"
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.a", 28.1f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.b", 28.2f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.extra", 28.99f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.a", 28.1)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.b", 28.2)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 028.extra", 28.99)
}
@Test
fun `Chapter containing dot v2`() {
val mangaTitle = "random"
assertChapter(mangaTitle, "Vol.1 Ch.5v.2: Alones", 5f)
assertChapter(mangaTitle, "Vol.1 Ch.5v.2: Alones", 5.0)
}
@Test
fun `Number in manga title`() {
val mangaTitle = "Ayame 14"
assertChapter(mangaTitle, "Ayame 14 1 - The summer of 14", 1f)
assertChapter(mangaTitle, "Ayame 14 1 - The summer of 14", 1.0)
}
@Test
fun `Space between ch x`() {
val mangaTitle = "Mokushiroku Alice"
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch. 4: Misrepresentation", 4f)
assertChapter(mangaTitle, "Mokushiroku Alice Vol.1 Ch. 4: Misrepresentation", 4.0)
}
@Test
fun `Chapter title with ch substring`() {
val mangaTitle = "Ayame 14"
assertChapter(mangaTitle, "Vol.1 Ch.1: March 25 (First Day Cohabiting)", 1f)
assertChapter(mangaTitle, "Vol.1 Ch.1: March 25 (First Day Cohabiting)", 1.0)
}
@Test
fun `Chapter containing multiple zeros`() {
val mangaTitle = "random"
assertChapter(mangaTitle, "Vol.001 Ch.003: Kaguya Doesn't Know Much", 3f)
assertChapter(mangaTitle, "Vol.001 Ch.003: Kaguya Doesn't Know Much", 3.0)
}
@Test
fun `Chapter with version before number`() {
val mangaTitle = "Onepunch-Man"
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 086 : Creeping Darkness [3]", 86f)
assertChapter(mangaTitle, "Onepunch-Man Punch Ver002 086 : Creeping Darkness [3]", 86.0)
}
@Test
fun `Version attached to chapter number`() {
val mangaTitle = "Ansatsu Kyoushitsu"
assertChapter(mangaTitle, "Ansatsu Kyoushitsu 011v002: Assembly Time", 11f)
assertChapter(mangaTitle, "Ansatsu Kyoushitsu 011v002: Assembly Time", 11.0)
}
/**
@ -168,99 +168,99 @@ class ChapterRecognitionTest {
fun `Number after manga title with chapter in chapter title case`() {
val mangaTitle = "Tokyo ESP"
assertChapter(mangaTitle, "Tokyo ESP 027: Part 002: Chapter 001", 027f)
assertChapter(mangaTitle, "Tokyo ESP 027: Part 002: Chapter 001", 027.0)
}
@Test
fun `Unparseable chapter`() {
val mangaTitle = "random"
assertChapter(mangaTitle, "Foo", -1f)
assertChapter(mangaTitle, "Foo", -1.0)
}
@Test
fun `Chapter with time in title`() {
val mangaTitle = "random"
assertChapter(mangaTitle, "Fairy Tail 404: 00:00", 404f)
assertChapter(mangaTitle, "Fairy Tail 404: 00:00", 404.0)
}
@Test
fun `Chapter with alpha without dot`() {
val mangaTitle = "random"
assertChapter(mangaTitle, "Asu No Yoichi 19a", 19.1f)
assertChapter(mangaTitle, "Asu No Yoichi 19a", 19.1)
}
@Test
fun `Chapter title containing extra and vol`() {
val mangaTitle = "Fairy Tail"
assertChapter(mangaTitle, "Fairy Tail 404.extravol002", 404.99f)
assertChapter(mangaTitle, "Fairy Tail 404 extravol002", 404.99f)
assertChapter(mangaTitle, "Fairy Tail 404.extravol002", 404.99)
assertChapter(mangaTitle, "Fairy Tail 404 extravol002", 404.99)
}
@Test
fun `Chapter title containing omake (japanese extra) and vol`() {
val mangaTitle = "Fairy Tail"
assertChapter(mangaTitle, "Fairy Tail 404.omakevol002", 404.98f)
assertChapter(mangaTitle, "Fairy Tail 404 omakevol002", 404.98f)
assertChapter(mangaTitle, "Fairy Tail 404.omakevol002", 404.98)
assertChapter(mangaTitle, "Fairy Tail 404 omakevol002", 404.98)
}
@Test
fun `Chapter title containing special and vol`() {
val mangaTitle = "Fairy Tail"
assertChapter(mangaTitle, "Fairy Tail 404.specialvol002", 404.97f)
assertChapter(mangaTitle, "Fairy Tail 404 specialvol002", 404.97f)
assertChapter(mangaTitle, "Fairy Tail 404.specialvol002", 404.97)
assertChapter(mangaTitle, "Fairy Tail 404 specialvol002", 404.97)
}
@Test
fun `Chapter title containing commas`() {
val mangaTitle = "One Piece"
assertChapter(mangaTitle, "One Piece 300,a", 300.1f)
assertChapter(mangaTitle, "One Piece Ch,123,extra", 123.99f)
assertChapter(mangaTitle, "One Piece the sunny, goes swimming 024,005", 24.005f)
assertChapter(mangaTitle, "One Piece 300,a", 300.1)
assertChapter(mangaTitle, "One Piece Ch,123,extra", 123.99)
assertChapter(mangaTitle, "One Piece the sunny, goes swimming 024,005", 24.005)
}
@Test
fun `Chapter title containing hyphens`() {
val mangaTitle = "Solo Leveling"
assertChapter(mangaTitle, "ch 122-a", 122.1f)
assertChapter(mangaTitle, "Solo Leveling Ch.123-extra", 123.99f)
assertChapter(mangaTitle, "Solo Leveling, 024-005", 24.005f)
assertChapter(mangaTitle, "Ch.191-200 Read Online", 191.200f)
assertChapter(mangaTitle, "ch 122-a", 122.1)
assertChapter(mangaTitle, "Solo Leveling Ch.123-extra", 123.99)
assertChapter(mangaTitle, "Solo Leveling, 024-005", 24.005)
assertChapter(mangaTitle, "Ch.191-200 Read Online", 191.200)
}
@Test
fun `Chapters containing season`() {
assertChapter("D.I.C.E", "D.I.C.E[Season 001] Ep. 007", 7f)
assertChapter("D.I.C.E", "D.I.C.E[Season 001] Ep. 007", 7.0)
}
@Test
fun `Chapters in format sx - chapter xx`() {
assertChapter("The Gamer", "S3 - Chapter 20", 20f)
assertChapter("The Gamer", "S3 - Chapter 20", 20.0)
}
@Test
fun `Chapters ending with s`() {
assertChapter("One Outs", "One Outs 001", 1f)
assertChapter("One Outs", "One Outs 001", 1.0)
}
@Test
fun `Chapters containing ordinals`() {
val mangaTitle = "The Sister of the Woods with a Thousand Young"
assertChapter(mangaTitle, "The 1st Night", 1f)
assertChapter(mangaTitle, "The 2nd Night", 2f)
assertChapter(mangaTitle, "The 3rd Night", 3f)
assertChapter(mangaTitle, "The 4th Night", 4f)
assertChapter(mangaTitle, "The 1st Night", 1.0)
assertChapter(mangaTitle, "The 2nd Night", 2.0)
assertChapter(mangaTitle, "The 3rd Night", 3.0)
assertChapter(mangaTitle, "The 4th Night", 4.0)
}
private fun assertChapter(mangaTitle: String, name: String, expected: Float) {
private fun assertChapter(mangaTitle: String, name: String, expected: Double) {
ChapterRecognition.parseChapterNumber(mangaTitle, name) shouldBe expected
}
}

View file

@ -12,73 +12,73 @@ class MissingItemsTest {
@Test
fun `missingItemsCount returns 0 when empty list`() {
emptyList<Float>().missingItemsCount() shouldBe 0
emptyList<Double>().missingItemsCount() shouldBe 0
}
@Test
fun `missingItemsCount returns 0 when all unknown item numbers`() {
listOf(-1f, -1f, -1f).missingItemsCount() shouldBe 0
listOf(-1.0, -1.0, -1.0).missingItemsCount() shouldBe 0
}
@Test
fun `missingItemsCount handles repeated base item numbers`() {
listOf(1f, 1.0f, 1.1f, 1.5f, 1.6f, 1.99f).missingItemsCount() shouldBe 0
listOf(1.0, 1.0, 1.1, 1.5, 1.6, 1.99).missingItemsCount() shouldBe 0
}
@Test
fun `missingItemsCount returns number of missing items`() {
listOf(-1f, 1f, 2f, 2.2f, 4f, 6f, 10f, 11f).missingItemsCount() shouldBe 5
listOf(-1.0, 1.0, 2.0, 2.2, 4.0, 6.0, 10.0, 10.0).missingItemsCount() shouldBe 5
}
@Test
fun `calculateChapterGap returns difference`() {
calculateChapterGap(chapter(10f), chapter(9f)) shouldBe 0f
calculateChapterGap(chapter(10f), chapter(8f)) shouldBe 1f
calculateChapterGap(chapter(10f), chapter(8.5f)) shouldBe 1f
calculateChapterGap(chapter(10f), chapter(1.1f)) shouldBe 8f
calculateChapterGap(chapter(10.0), chapter(9.0)) shouldBe 0f
calculateChapterGap(chapter(10.0), chapter(8.0)) shouldBe 1f
calculateChapterGap(chapter(10.0), chapter(8.5)) shouldBe 1f
calculateChapterGap(chapter(10.0), chapter(1.1)) shouldBe 8f
calculateChapterGap(10f, 9f) shouldBe 0f
calculateChapterGap(10f, 8f) shouldBe 1f
calculateChapterGap(10f, 8.5f) shouldBe 1f
calculateChapterGap(10f, 1.1f) shouldBe 8f
calculateChapterGap(10.0, 9.0) shouldBe 0f
calculateChapterGap(10.0, 8.0) shouldBe 1f
calculateChapterGap(10.0, 8.5) shouldBe 1f
calculateChapterGap(10.0, 1.1) shouldBe 8f
}
@Test
fun `calculateChapterGap returns 0 if either are not valid chapter numbers`() {
calculateChapterGap(chapter(-1f), chapter(10f)) shouldBe 0
calculateChapterGap(chapter(99f), chapter(-1f)) shouldBe 0
calculateChapterGap(chapter(-1.0), chapter(10.0)) shouldBe 0
calculateChapterGap(chapter(99.0), chapter(-1.0)) shouldBe 0
calculateChapterGap(-1f, 10f) shouldBe 0
calculateChapterGap(99f, -1f) shouldBe 0
calculateChapterGap(-1.0, 10.0) shouldBe 0
calculateChapterGap(99.0, -1.0) shouldBe 0
}
private fun chapter(number: Float) = Chapter.create().copy(
private fun chapter(number: Double) = Chapter.create().copy(
chapterNumber = number,
)
@Test
fun `calculateEpisodeGap returns difference`() {
calculateEpisodeGap(episode(10f), episode(9f)) shouldBe 0f
calculateEpisodeGap(episode(10f), episode(8f)) shouldBe 1f
calculateEpisodeGap(episode(10f), episode(8.5f)) shouldBe 1f
calculateEpisodeGap(episode(10f), episode(1.1f)) shouldBe 8f
calculateEpisodeGap(episode(10.0), episode(9.0)) shouldBe 0f
calculateEpisodeGap(episode(10.0), episode(8.0)) shouldBe 1f
calculateEpisodeGap(episode(10.0), episode(8.5)) shouldBe 1f
calculateEpisodeGap(episode(10.0), episode(1.1)) shouldBe 8f
calculateEpisodeGap(10f, 9f) shouldBe 0f
calculateEpisodeGap(10f, 8f) shouldBe 1f
calculateEpisodeGap(10f, 8.5f) shouldBe 1f
calculateEpisodeGap(10f, 1.1f) shouldBe 8f
calculateEpisodeGap(10.0, 9.0) shouldBe 0f
calculateEpisodeGap(10.0, 8.0) shouldBe 1f
calculateEpisodeGap(10.0, 8.5) shouldBe 1f
calculateEpisodeGap(10.0, 1.1) shouldBe 8f
}
@Test
fun `calculateEpisodeGap returns 0 if either are not valid episode numbers`() {
calculateEpisodeGap(episode(-1f), episode(10f)) shouldBe 0
calculateEpisodeGap(episode(99f), episode(-1f)) shouldBe 0
calculateEpisodeGap(episode(-1.0), episode(10.0)) shouldBe 0
calculateEpisodeGap(episode(99.0), episode(-1.0)) shouldBe 0
calculateEpisodeGap(-1f, 10f) shouldBe 0
calculateEpisodeGap(99f, -1f) shouldBe 0
calculateEpisodeGap(-1.0, 10.0) shouldBe 0
calculateEpisodeGap(99.0, -1.0) shouldBe 0
}
private fun episode(number: Float) = Episode.create().copy(
private fun episode(number: Double) = Episode.create().copy(
episodeNumber = number,
)
}

View file

@ -26,3 +26,5 @@ android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
android.experimental.useDefaultDebugSigningConfigForProfileableBuildtypes=true

View file

@ -1,5 +1,5 @@
[versions]
agp_version = "8.1.0"
agp_version = "8.0.2"
lifecycle_version = "2.6.1"
paging_version = "3.2.0"
@ -28,10 +28,10 @@ guava = "com.google.guava:guava:32.0.1-android"
paging-runtime = { module = "androidx.paging:paging-runtime", version.ref = "paging_version" }
paging-compose = { module = "androidx.paging:paging-compose", version.ref = "paging_version" }
benchmark-macro = "androidx.benchmark:benchmark-macro-junit4:1.1.1"
test-ext = "androidx.test.ext:junit-ktx:1.1.5"
test-espresso-core = "androidx.test.espresso:espresso-core:3.5.1"
test-uiautomator = "androidx.test.uiautomator:uiautomator:2.2.0"
benchmark-macro = "androidx.benchmark:benchmark-macro-junit4:1.2.0-beta02"
test-ext = "androidx.test.ext:junit-ktx:1.2.0-alpha01"
test-espresso-core = "androidx.test.espresso:espresso-core:3.6.0-alpha01"
test-uiautomator = "androidx.test.uiautomator:uiautomator:2.3.0-alpha04"
[bundles]
lifecycle = ["lifecycle-common", "lifecycle-process", "lifecycle-runtimektx"]

View file

@ -79,7 +79,6 @@ leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", versi
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-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-gradle = { module = "app.cash.sqldelight:gradle-plugin", version.ref = "sqldelight" }
@ -108,7 +107,7 @@ js-engine = ["quickjs-android"]
sqlite = ["sqlite-framework", "sqlite-ktx", "sqlite-android"]
coil = ["coil-core", "coil-gif", "coil-compose"]
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"]
richtext = ["richtext-commonmark", "richtext-m3"]
test = ["junit", "kotest-assertions", "mockk"]

View file

@ -8,6 +8,7 @@ android {
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["androidx.benchmark.enabledRules"] = "BaselineProfile"
}
buildTypes {
@ -17,7 +18,7 @@ android {
create("benchmark") {
isDebuggable = true
signingConfig = getByName("debug").signingConfig
matchingFallbacks += listOf("release")
matchingFallbacks.add("release")
}
}

View file

@ -1,19 +1,17 @@
package tachiyomi.macrobenchmark
import androidx.benchmark.macro.ExperimentalBaselineProfilesApi
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.uiautomator.By
import org.junit.Rule
import org.junit.Test
@OptIn(ExperimentalBaselineProfilesApi::class)
class BaselineProfileGenerator {
@get:Rule
val baselineProfileRule = BaselineProfileRule()
@Test
fun generate() = baselineProfileRule.collectBaselineProfile(
fun generate() = baselineProfileRule.collect(
packageName = "xyz.jmir.tachiyomi.mi.benchmark",
profileBlock = {
pressHome()

View file

@ -181,11 +181,7 @@ actual class LocalAnimeSource(
}
date_upload = episodeFile.lastModified()
val episodeNumber = EpisodeRecognition.parseEpisodeNumber(
anime.title,
this.name,
this.episode_number,
)
val episodeNumber = EpisodeRecognition.parseEpisodeNumber(anime.title, this.name, this.episode_number.toDouble()).toFloat()
episode_number = episodeNumber
// Overwrite data from episodes.json file

View file

@ -282,11 +282,9 @@ actual class LocalMangaSource(
}
date_upload = chapterFile.lastModified()
val chapterNumber = ChapterRecognition.parseChapterNumber(
manga.title,
this.name,
this.chapter_number,
)
val chapterNumber = ChapterRecognition
.parseChapterNumber(manga.title, this.name, this.chapter_number.toDouble())
.toFloat()
chapter_number = chapterNumber
val format = Format.valueOf(chapterFile)