From 6b942a8e07c305598aa7a233dfd429cbb61ffa0d Mon Sep 17 00:00:00 2001 From: Stefan Ostermann Date: Mon, 22 Sep 2025 22:07:43 +0200 Subject: [PATCH] [ai] alphabetical order --- src/DirectoryNode.cpp | 67 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/src/DirectoryNode.cpp b/src/DirectoryNode.cpp index 28fc1f5..8bb28fe 100644 --- a/src/DirectoryNode.cpp +++ b/src/DirectoryNode.cpp @@ -1,5 +1,6 @@ #include "DirectoryNode.h" #include "globals.h" +#include DirectoryNode::DirectoryNode(const String &nodeName) : name(nodeName), currentPlaying(nullptr) @@ -97,10 +98,9 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath) mp3Files.clear(); ids.clear(); - // Reserve memory to reduce heap fragmentation (optimization 3) - subdirectories.reserve(8); // Reserve space for 8 subdirectories - mp3Files.reserve(16); // Reserve space for 16 MP3 files - ids.reserve(16); // Reserve space for 16 IDs + // First collect entries so we can sort them alphabetically + std::vector dirNames; + std::vector fileNames; File rootDir = SD.open(currentPath); while (true) @@ -113,22 +113,61 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath) if (entry.isDirectory() && entry.name()[0] != '.' && strcmp(entry.name(), sys_dir.c_str())) { - DirectoryNode *newNode = new DirectoryNode(entry.name()); - subdirectories.push_back(newNode); - newNode->buildDirectoryTree((String(currentPath) + entry.name()).c_str()); + dirNames.push_back(String(entry.name())); } - else if (String(entry.name()).endsWith(".mp3") || String(entry.name()).endsWith(".MP3")) + else { - String fullPath = String(currentPath); - if (!fullPath.endsWith("/")) - fullPath += "/"; - fullPath += entry.name(); - mp3Files.push_back(fullPath); - ids.push_back(getNextId()); + String entryName = entry.name(); + if (entryName.endsWith(".mp3") || entryName.endsWith(".MP3")) + { + fileNames.push_back(entryName); + } } entry.close(); } rootDir.close(); + + // Case-insensitive alphabetical sort + auto ciLess = [](const String &a, const String &b) { + String al = a; + String bl = b; + al.toLowerCase(); + bl.toLowerCase(); + return al.compareTo(bl) < 0; + }; + std::sort(dirNames.begin(), dirNames.end(), ciLess); + std::sort(fileNames.begin(), fileNames.end(), ciLess); + + // Reserve memory to reduce heap fragmentation + subdirectories.reserve(dirNames.size()); + mp3Files.reserve(fileNames.size()); + ids.reserve(fileNames.size()); + + // Create subdirectories in alphabetical order + for (const String &dirName : dirNames) + { + DirectoryNode *newNode = new DirectoryNode(dirName); + subdirectories.push_back(newNode); + + String childPath = String(currentPath); + if (!childPath.endsWith("/")) + childPath += "/"; + childPath += dirName; + + newNode->buildDirectoryTree(childPath.c_str()); + } + + // Add MP3 files in alphabetical order + for (const String &fileName : fileNames) + { + String fullPath = String(currentPath); + if (!fullPath.endsWith("/")) + fullPath += "/"; + fullPath += fileName; + + mp3Files.push_back(fullPath); + ids.push_back(getNextId()); + } } void DirectoryNode::printDirectoryTree(int level) const