diff --git a/src/RecentBooksStore.cpp b/src/RecentBooksStore.cpp index 05492d2a..276eb522 100644 --- a/src/RecentBooksStore.cpp +++ b/src/RecentBooksStore.cpp @@ -1,11 +1,15 @@ #include "RecentBooksStore.h" +#include #include #include #include +#include #include +#include "util/StringUtils.h" + namespace { constexpr uint8_t RECENT_BOOKS_FILE_VERSION = 3; constexpr char RECENT_BOOKS_FILE[] = "/.crosspoint/recent.bin"; @@ -59,6 +63,34 @@ bool RecentBooksStore::saveToFile() const { return true; } +RecentBook RecentBooksStore::getDataFromBook(std::string path) const { + std::string lastBookFileName = ""; + const size_t lastSlash = path.find_last_of('/'); + if (lastSlash != std::string::npos) { + lastBookFileName = path.substr(lastSlash + 1); + } + + Serial.printf("Loading recent book: %s\n", path.c_str()); + + // If epub, try to load the metadata for title/author and cover + if (StringUtils::checkFileExtension(lastBookFileName, ".epub")) { + Epub epub(path, "/.crosspoint"); + epub.load(false); + return RecentBook{path, epub.getTitle(), epub.getAuthor(), epub.getThumbBmpPath()}; + } else if (StringUtils::checkFileExtension(lastBookFileName, ".xtch") || + StringUtils::checkFileExtension(lastBookFileName, ".xtc")) { + // Handle XTC file + Xtc xtc(path, "/.crosspoint"); + if (xtc.load()) { + return RecentBook{path, xtc.getTitle(), xtc.getAuthor(), xtc.getThumbBmpPath()}; + } + } else if (StringUtils::checkFileExtension(lastBookFileName, ".txt") || + StringUtils::checkFileExtension(lastBookFileName, ".md")) { + return RecentBook{path, lastBookFileName, "", ""}; + } + return RecentBook{path, "", "", ""}; +} + bool RecentBooksStore::loadFromFile() { FsFile inputFile; if (!SdMan.openFileForRead("RBS", RECENT_BOOKS_FILE, inputFile)) { @@ -68,7 +100,7 @@ bool RecentBooksStore::loadFromFile() { uint8_t version; serialization::readPod(inputFile, version); if (version != RECENT_BOOKS_FILE_VERSION) { - if (version == 1) { + if (version == 1 || version == 2) { // Old version, just read paths uint8_t count; serialization::readPod(inputFile, count); @@ -77,24 +109,18 @@ bool RecentBooksStore::loadFromFile() { for (uint8_t i = 0; i < count; i++) { std::string path; serialization::readString(inputFile, path); - // Title and author will be empty, they will be filled when the book is - // opened again - recentBooks.push_back({path, "", "", ""}); - } - } else if (version == 2) { - // Old version, just read paths, titles and authors - uint8_t count; - serialization::readPod(inputFile, count); - recentBooks.clear(); - recentBooks.reserve(count); - for (uint8_t i = 0; i < count; i++) { - std::string path, title, author; - serialization::readString(inputFile, path); - serialization::readString(inputFile, title); - serialization::readString(inputFile, author); - // Title and author will be empty, they will be filled when the book is - // opened again - recentBooks.push_back({path, title, author, ""}); + + // load book to get missing data + RecentBook book = getDataFromBook(path); + if (book.title.empty() && book.author.empty() && version == 2) { + // Fall back to loading what we can from the store + std::string title, author; + serialization::readString(inputFile, title); + serialization::readString(inputFile, author); + recentBooks.push_back({path, title, author, ""}); + } else { + recentBooks.push_back(book); + } } } else { Serial.printf("[%lu] [RBS] Deserialization failed: Unknown version %u\n", millis(), version); diff --git a/src/RecentBooksStore.h b/src/RecentBooksStore.h index 16b7a8e2..6f6a164a 100644 --- a/src/RecentBooksStore.h +++ b/src/RecentBooksStore.h @@ -36,6 +36,7 @@ class RecentBooksStore { bool saveToFile() const; bool loadFromFile(); + RecentBook getDataFromBook(std::string path) const; }; // Helper macro to access recent books store diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index 555045c7..4de12d18 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -58,9 +58,11 @@ void TxtReaderActivity::onEnter() { txt->setupCacheDir(); // Save current txt as last opened file and add to recent books - APP_STATE.openEpubPath = txt->getPath(); + auto filePath = txt->getPath(); + auto fileName = filePath.substr(filePath.rfind('/') + 1); + APP_STATE.openEpubPath = filePath; APP_STATE.saveToFile(); - RECENT_BOOKS.addBook(txt->getPath(), "", "", ""); + RECENT_BOOKS.addBook(filePath, fileName, "", ""); // Trigger first update updateRequired = true;