diff --git a/src/RecentBooksStore.cpp b/src/RecentBooksStore.cpp index b34f8523..fc0d89a4 100644 --- a/src/RecentBooksStore.cpp +++ b/src/RecentBooksStore.cpp @@ -22,6 +22,9 @@ RecentBooksStore RecentBooksStore::instance; void RecentBooksStore::addBook(const std::string& path, const std::string& title, const std::string& author, const std::string& coverBmpPath) { + // Drop stale entries first so a new add can't evict a valid book in their stead. + pruneMissing(); + // Remove existing entry if present auto it = std::find_if(recentBooks.begin(), recentBooks.end(), [&](const RecentBook& book) { return book.path == path; }); @@ -53,6 +56,14 @@ void RecentBooksStore::updateBook(const std::string& path, const std::string& ti } } +bool RecentBooksStore::isMissing(const RecentBook& book) { return !Storage.exists(book.path.c_str()); } + +bool RecentBooksStore::pruneMissing() { + const size_t before = recentBooks.size(); + recentBooks.erase(std::remove_if(recentBooks.begin(), recentBooks.end(), &isMissing), recentBooks.end()); + return recentBooks.size() != before; +} + bool RecentBooksStore::saveToFile() const { Storage.mkdir("/.crosspoint"); return JsonSettingsIO::saveRecentBooks(*this, RECENT_BOOKS_FILE_JSON); diff --git a/src/RecentBooksStore.h b/src/RecentBooksStore.h index 5d98ce83..293d4f6f 100644 --- a/src/RecentBooksStore.h +++ b/src/RecentBooksStore.h @@ -37,6 +37,13 @@ class RecentBooksStore { void updateBook(const std::string& path, const std::string& title, const std::string& author, const std::string& coverBmpPath); + // True if the book's backing file is no longer present on the SD card. + static bool isMissing(const RecentBook& book); + + // Remove entries whose backing file is no longer on the SD card. + // Returns true if any entry was removed. Does not persist — caller decides. + bool pruneMissing(); + // Get the list of recent books (most recent first) const std::vector& getBooks() const { return recentBooks; } diff --git a/src/activities/home/HomeActivity.cpp b/src/activities/home/HomeActivity.cpp index 7bb0a340..76457491 100644 --- a/src/activities/home/HomeActivity.cpp +++ b/src/activities/home/HomeActivity.cpp @@ -43,7 +43,7 @@ void HomeActivity::loadRecentBooks(int maxBooks) { } // Skip if file no longer exists - if (!Storage.exists(book.path.c_str())) { + if (RecentBooksStore::isMissing(book)) { continue; } diff --git a/src/activities/home/RecentBooksActivity.cpp b/src/activities/home/RecentBooksActivity.cpp index 6ba8f8cf..56c6c6fb 100644 --- a/src/activities/home/RecentBooksActivity.cpp +++ b/src/activities/home/RecentBooksActivity.cpp @@ -15,23 +15,17 @@ namespace { constexpr unsigned long GO_HOME_MS = 1000; } // namespace -void RecentBooksActivity::loadRecentBooks() { - recentBooks.clear(); - const auto& books = RECENT_BOOKS.getBooks(); - recentBooks.reserve(books.size()); - - for (const auto& book : books) { - // Skip if file no longer exists - if (!Storage.exists(book.path.c_str())) { - continue; - } - recentBooks.push_back(book); - } -} +void RecentBooksActivity::loadRecentBooks() { recentBooks = RECENT_BOOKS.getBooks(); } void RecentBooksActivity::onEnter() { Activity::onEnter(); + // Prune entries whose backing files are gone; this is one of two interaction + // points where the persistent store gets cleaned (the other is addBook). + if (RECENT_BOOKS.pruneMissing()) { + RECENT_BOOKS.saveToFile(); + } + // Load data loadRecentBooks();