Regenerate cover thumbnails if cachedir is empty

This commit is contained in:
jpirnay
2026-05-19 12:02:25 +02:00
parent 92b4f491db
commit a1f187b139
+55 -24
View File
@@ -198,8 +198,52 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
const auto thumbSizes = GUI.getCoverThumbSizes(coverHeight);
// Called at every early-return point where a cover was just written to disk.
// Invalidates the carousel frame cache so tryFastHomeRender re-renders the tile
// with the new BMP rather than compositing the stale placeholder frame.
const auto onCoverGenerated = [this]() {
UITheme::getInstance().getMutableTheme().invalidateFrameCache();
coverRendered = false;
nextRecentCoverIndex++;
recentsLoading = false;
requestUpdate();
};
for (; nextRecentCoverIndex < recentBooks.size(); nextRecentCoverIndex++) {
RecentBook& book = recentBooks[nextRecentCoverIndex];
// If coverBmpPath was previously cleared (failed cover extraction) or is missing after
// a cache wipe, attempt to generate it now using the full load path (buildIfMissing=true).
if (book.coverBmpPath.empty() && Storage.exists(book.path.c_str())) {
if (FsHelpers::hasEpubExtension(book.path)) {
Epub epub(book.path, "/.crosspoint");
if (epub.load(true, true)) {
const std::string thumbPath = epub.getThumbBmpPath();
bool success = thumbSizes.empty() ? epub.generateThumbBmp(coverHeight)
: epub.generateThumbBmp(thumbSizes[0].first, thumbSizes[0].second);
if (success) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, thumbPath);
book.coverBmpPath = thumbPath;
LOG_DBG("HOME", "Generated missing cover for %s", book.path.c_str());
}
}
} else if (FsHelpers::hasXtcExtension(book.path)) {
Xtc xtc(book.path, "/.crosspoint");
if (xtc.load()) {
const std::string thumbPath = xtc.getThumbBmpPath();
bool success = thumbSizes.empty() ? xtc.generateThumbBmp(coverHeight)
: xtc.generateThumbBmp(thumbSizes[0].first, thumbSizes[0].second);
if (success) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, thumbPath);
book.coverBmpPath = thumbPath;
LOG_DBG("HOME", "Generated missing cover for %s", book.path.c_str());
}
}
}
onCoverGenerated();
return;
}
if (!book.coverBmpPath.empty()) {
// Sidecar covers (JPG/PNG paths stored directly) must be converted to BMP thumbnails
// and the stored coverBmpPath updated to the cache path with [WIDTH]x[HEIGHT] placeholder.
@@ -242,10 +286,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
// Don't permanently clear the path on failure — keep the raw sidecar path
// so the next home visit can retry (e.g. after more memory becomes available).
}
coverRendered = false;
nextRecentCoverIndex++;
recentsLoading = false;
requestUpdate();
onCoverGenerated();
return;
}
}
@@ -266,7 +307,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
bool success = true;
if (FsHelpers::hasEpubExtension(book.path)) {
Epub epub(book.path, "/.crosspoint");
epub.load(false, true);
epub.load(true, true);
for (const auto& sz : thumbSizes) {
const std::string path = UITheme::getCoverThumbPath(book.coverBmpPath, sz.first, sz.second);
if (!Storage.exists(path.c_str())) success = epub.generateThumbBmp(sz.first, sz.second) && success;
@@ -284,10 +325,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, "");
book.coverBmpPath = "";
}
coverRendered = false;
nextRecentCoverIndex++;
recentsLoading = false;
requestUpdate();
onCoverGenerated();
return;
}
} else {
@@ -295,16 +333,13 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
if (!Storage.exists(coverPath.c_str())) {
if (FsHelpers::hasEpubExtension(book.path)) {
Epub epub(book.path, "/.crosspoint");
epub.load(false, true);
epub.load(true, true);
bool success = epub.generateThumbBmp(coverHeight);
if (!success) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, "");
book.coverBmpPath = "";
}
coverRendered = false;
nextRecentCoverIndex++;
recentsLoading = false;
requestUpdate();
onCoverGenerated();
return;
} else if (FsHelpers::hasXtcExtension(book.path)) {
Xtc xtc(book.path, "/.crosspoint");
@@ -314,10 +349,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, "");
book.coverBmpPath = "";
}
coverRendered = false;
nextRecentCoverIndex++;
recentsLoading = false;
requestUpdate();
onCoverGenerated();
return;
}
}
@@ -433,6 +465,11 @@ void HomeActivity::loop() {
const bool isCarousel = (GUI.getHomeNavigation() == HomeNavigation::Carousel);
if (isCarousel) {
if (firstRenderDone && !recentsLoaded && !recentsLoading) {
loadRecentCovers(UITheme::getInstance().getMetrics().homeCoverHeight);
return;
}
const int bookCount = static_cast<int>(recentBooks.size());
const int menuItemCount = static_cast<int>(menuEntries.size());
const bool inCarouselRow = (selectorIndex < bookCount);
@@ -529,9 +566,6 @@ void HomeActivity::render(RenderLock&&) {
if (!firstRenderDone) {
firstRenderDone = true;
requestUpdate();
} else if (!recentsLoaded && !recentsLoading) {
recentsLoading = true;
loadRecentCovers(metrics.homeCoverHeight);
}
return;
}
@@ -571,9 +605,6 @@ void HomeActivity::render(RenderLock&&) {
if (!firstRenderDone) {
firstRenderDone = true;
requestUpdate();
} else if (!recentsLoaded && !recentsLoading) {
recentsLoading = true;
loadRecentCovers(getHomeCoverRenderHeight(computeHomeScreenLayout(metrics, contentRect.height, menuCount)));
}
}