diff --git a/src/activities/home/MyLibraryActivity.cpp b/src/activities/home/MyLibraryActivity.cpp index 52b2fe13..3d5dbf1a 100644 --- a/src/activities/home/MyLibraryActivity.cpp +++ b/src/activities/home/MyLibraryActivity.cpp @@ -16,11 +16,53 @@ constexpr unsigned long GO_HOME_MS = 1000; void sortFileList(std::vector& strs) { std::sort(begin(strs), end(strs), [](const std::string& str1, const std::string& str2) { - if (str1.back() == '/' && str2.back() != '/') return true; - if (str1.back() != '/' && str2.back() == '/') return false; - return lexicographical_compare( - begin(str1), end(str1), begin(str2), end(str2), - [](const char& char1, const char& char2) { return tolower(char1) < tolower(char2); }); + // Directories first + bool isDir1 = str1.back() == '/'; + bool isDir2 = str2.back() == '/'; + if (isDir1 != isDir2) return isDir1; + + // Start naive natural sort + const char* s1 = str1.c_str(); + const char* s2 = str2.c_str(); + + // Iterate while both strings have characters + while (*s1 && *s2) { + // Check if both are at the start of a number + if (isdigit(*s1) && isdigit(*s2)) { + // Skip leading zeros and track them + const char* start1 = s1; + const char* start2 = s2; + while (*s1 == '0') s1++; + while (*s2 == '0') s2++; + + // Count digits to compare lengths first + int len1 = 0, len2 = 0; + while (isdigit(s1[len1])) len1++; + while (isdigit(s2[len2])) len2++; + + // Different length so return smaller integer value + if (len1 != len2) return len1 < len2; + + // Same length so compare digit by digit + for (int i = 0; i < len1; i++) { + if (s1[i] != s2[i]) return s1[i] < s2[i]; + } + + // Numbers equal so advance pointers + s1 += len1; + s2 += len2; + } else { + // Regular case-insensitive character comparison + char c1 = tolower(*s1); + char c2 = tolower(*s2); + if (c1 != c2) return c1 < c2; + s1++; + s2++; + } + } + + // One string is prefix of other + return *s1 == '\0' && *s2 != '\0'; }); }