add timestamp to cachebust covers

This commit is contained in:
Mio.
2025-07-14 07:17:47 +02:00
parent 15f5587427
commit d37600f74b

View File

@@ -998,36 +998,34 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
val libraryType = getLibraryType(seriesId) val libraryType = getLibraryType(seriesId)
val isComicLibrary = libraryType == LibraryTypeEnum.Comic || libraryType == LibraryTypeEnum.ComicVine val isComicLibrary = libraryType == LibraryTypeEnum.Comic || libraryType == LibraryTypeEnum.ComicVine
val coverCandidates = mutableListOf<Triple<String, Boolean, Float>>() // (url, isUnread, number)
val coverCandidates = mutableListOf<Triple<String, Boolean, Float>>() val chapterMap = mutableMapOf<String, ChapterDto>()
val volumeMap = mutableMapOf<String, VolumeDto>()
for (volume in volumes) { for (volume in volumes) {
// Issue: use chapter covers // Issue: use chapter covers
if (isComicLibrary && volume.minNumber.toInt() == KavitaConstants.UNNUMBERED_VOLUME) { if (isComicLibrary && volume.minNumber.toInt() == KavitaConstants.UNNUMBERED_VOLUME) {
coverCandidates += volume.chapters for (chapter in volume.chapters) {
.filterNot { it.coverImage.isBlank() } if (chapter.coverImage.isNotBlank()) {
.map { chapter -> val url = "$apiUrl/Image/chapter-cover?chapterId=${chapter.id}&apiKey=$apiKey"
Triple( coverCandidates.add(
"$apiUrl/Image/chapter-cover?chapterId=${chapter.id}&apiKey=$apiKey", Triple(url, chapter.pagesRead < chapter.pages, chapter.number.toFloatOrNull() ?: 0f)
chapter.pagesRead < chapter.pages,
chapter.number.toFloatOrNull() ?: 0f,
) )
chapterMap[url] = chapter
} }
} else if (!isComicLibrary) { }
// Manga: use volume cover if it has a SingleFileVolume chapter }
// Manga: use volume cover
else if (!isComicLibrary) {
val hasSingleFile = volume.chapters.any { chapter -> val hasSingleFile = volume.chapters.any { chapter ->
ChapterType.of(chapter, volume) == ChapterType.SingleFileVolume ChapterType.of(chapter, volume) == ChapterType.SingleFileVolume
} }
if (hasSingleFile && volume.coverImage.isNotBlank()) { if (hasSingleFile && volume.coverImage.isNotBlank()) {
val url = "$apiUrl/Image/volume-cover?volumeId=${volume.id}&apiKey=$apiKey"
val isUnread = volume.pagesRead < volume.pages val isUnread = volume.pagesRead < volume.pages
val volumeNumber = volume.minNumber.toFloat() val number = volume.minNumber.toFloat()
coverCandidates.add( coverCandidates.add(Triple(url, isUnread, number))
Triple( volumeMap[url] = volume
"$apiUrl/Image/volume-cover?volumeId=${volume.id}&apiKey=$apiKey",
isUnread,
volumeNumber,
),
)
} }
} }
} }
@@ -1040,7 +1038,22 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
.minByOrNull { it.third } .minByOrNull { it.third }
?: coverCandidates.maxByOrNull { it.third } ?: coverCandidates.maxByOrNull { it.third }
targetCover?.first ?: "$apiUrl/image/series-cover?seriesId=$seriesId&apiKey=$apiKey" targetCover?.first?.let { baseUrl ->
val timestamp = when {
baseUrl.contains("chapter-cover") -> {
val chapter = chapterMap[baseUrl]
chapter?.lastModifiedUtc
}
baseUrl.contains("volume-cover") -> {
val volume = volumeMap[baseUrl]
volume?.lastModified
}
else -> null
} ?: System.currentTimeMillis().toString()
// Append cache-busting timestamp to always get the latest cover
"$baseUrl&ts=$timestamp"
} ?: "$apiUrl/image/series-cover?seriesId=$seriesId&apiKey=$apiKey"
} catch (e: Exception) { } catch (e: Exception) {
Log.e(LOG_TAG, "Error fetching volumes for cover selection", e) Log.e(LOG_TAG, "Error fetching volumes for cover selection", e)
"$apiUrl/image/series-cover?seriesId=${result.seriesId ?: 0}&apiKey=$apiKey" "$apiUrl/image/series-cover?seriesId=${result.seriesId ?: 0}&apiKey=$apiKey"