diff --git a/src/esp32/config.h b/src/esp32/config.h index a73288e..3e19fac 100644 --- a/src/esp32/config.h +++ b/src/esp32/config.h @@ -118,7 +118,7 @@ const uint32_t SETUP_AP_DELAY = 20000; // open the AP when WiFi fails thi const uint32_t WIFI_CONNECT_TIMEOUT = 30000; const uint32_t WIFI_RESTART_TIME = 10UL * 60 * 1000; -#define FIRMWARE_VERSION "2.19.0" +#define FIRMWARE_VERSION "2.19.1" // Home Assistant device id (do not change: Home Assistant's entities are linked to it) const uint8_t HA_DEVICE_ID[] = {0x34, 0x86, 0x5d, 0x3a, 0x08, 0x28}; diff --git a/src/esp32/display/page_store.cpp b/src/esp32/display/page_store.cpp index fbbc17c..a2e4bc1 100644 --- a/src/esp32/display/page_store.cpp +++ b/src/esp32/display/page_store.cpp @@ -25,9 +25,29 @@ static String path(const char *name) return String(DIR) + "/" + name + EXTENSION; } +// The names of the stored pages, kept until a page is saved or deleted: listing the +// directory takes about 350 ms with 16 pages, and each exists() about 25 ms +static std::vector names; +static bool names_valid = false; + +static const std::vector &storedPageNames() +{ + if (!names_valid) + { + names = bitmapStorageAvailable() ? storedNames(DIR, EXTENSION) : std::vector(); + names_valid = true; + } + return names; +} + static bool storedPage(const char *name) { - return bitmapStorageAvailable() && validBitmapName(name) && LittleFS.exists(path(name)); + if (!bitmapStorageAvailable() || !validBitmapName(name)) + return false; + for (const String &stored : storedPageNames()) + if (stored == name) // like exists(): the file names are case-sensitive + return true; + return false; } void pageStoreBegin() @@ -48,7 +68,7 @@ std::vector listPages() for (int i = 0; i < builtinPageCount(); i++) if (!storedPage(builtinPageName(i))) list.push_back({builtinPageName(i), true, false}); - for (const String &name : storedNames(DIR, EXTENSION)) + for (const String &name : storedPageNames()) list.push_back({name, false, builtinPageName(name.c_str()) != nullptr}); return list; } @@ -99,7 +119,7 @@ const char *savePage(const char *name, const DynamicPage &page) return error; if (!bitmapStorageAvailable()) return "No storage (install the new flash layout over USB, see README)"; - if (!LittleFS.exists(path(name)) && storedNames(DIR, EXTENSION).size() >= (size_t)MAX_PAGES) + if (!storedPage(name) && storedPageNames().size() >= (size_t)MAX_PAGES) return "Too many pages, delete some first"; StoredPage *stored = new StoredPage; @@ -112,6 +132,7 @@ const char *savePage(const char *name, const DynamicPage &page) file.close(); delete stored; revision++; + names_valid = false; return ok ? nullptr : "Could not write the file (storage full?)"; } @@ -121,7 +142,9 @@ const char *deletePage(const char *name) return "Built-in pages can't be deleted"; if (!storedPage(name)) return "Page not found"; - if (!LittleFS.remove(path(name))) + bool removed = LittleFS.remove(path(name)); + names_valid = false; + if (!removed) return "Could not delete the file"; revision++; return nullptr; @@ -132,7 +155,9 @@ template static String findPage(F uses) { DynamicPage *page = new DynamicPage; String found; - for (const String &name : storedNames(DIR, EXTENSION)) + // A copy: loadPage() may list the directory again + std::vector list = storedPageNames(); + for (const String &name : list) if (loadPage(name.c_str(), *page) && uses(*page)) { found = name;