A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: use natural sort in file browser (#722)

## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement natural sort (e.g. "file1.txt, file2.txt, file10.txt" instead
of "file1.txt, file10.txt, file2.txt") for files in the
MyLibraryActivity menu

* **What changes are included?**

Modifies the `sortFileList` function under
`src/activities/home/MyLibraryActivity.cpp` to use natural sort as
opposed to lexicographical sort

## Additional Context

I wasn't entirely sure whether or not i should make this a configurable
option, but most file browsers and directory listing tools have this set
as an immutable default, so I opted against it.

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
specific areas to focus on).

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**NO**_

authored by

ThatCrispyToast and committed by
GitHub
b5d28a3a 14ef6256

+47 -5
+47 -5
src/activities/home/MyLibraryActivity.cpp
··· 16 16 17 17 void sortFileList(std::vector<std::string>& strs) { 18 18 std::sort(begin(strs), end(strs), [](const std::string& str1, const std::string& str2) { 19 - if (str1.back() == '/' && str2.back() != '/') return true; 20 - if (str1.back() != '/' && str2.back() == '/') return false; 21 - return lexicographical_compare( 22 - begin(str1), end(str1), begin(str2), end(str2), 23 - [](const char& char1, const char& char2) { return tolower(char1) < tolower(char2); }); 19 + // Directories first 20 + bool isDir1 = str1.back() == '/'; 21 + bool isDir2 = str2.back() == '/'; 22 + if (isDir1 != isDir2) return isDir1; 23 + 24 + // Start naive natural sort 25 + const char* s1 = str1.c_str(); 26 + const char* s2 = str2.c_str(); 27 + 28 + // Iterate while both strings have characters 29 + while (*s1 && *s2) { 30 + // Check if both are at the start of a number 31 + if (isdigit(*s1) && isdigit(*s2)) { 32 + // Skip leading zeros and track them 33 + const char* start1 = s1; 34 + const char* start2 = s2; 35 + while (*s1 == '0') s1++; 36 + while (*s2 == '0') s2++; 37 + 38 + // Count digits to compare lengths first 39 + int len1 = 0, len2 = 0; 40 + while (isdigit(s1[len1])) len1++; 41 + while (isdigit(s2[len2])) len2++; 42 + 43 + // Different length so return smaller integer value 44 + if (len1 != len2) return len1 < len2; 45 + 46 + // Same length so compare digit by digit 47 + for (int i = 0; i < len1; i++) { 48 + if (s1[i] != s2[i]) return s1[i] < s2[i]; 49 + } 50 + 51 + // Numbers equal so advance pointers 52 + s1 += len1; 53 + s2 += len2; 54 + } else { 55 + // Regular case-insensitive character comparison 56 + char c1 = tolower(*s1); 57 + char c2 = tolower(*s2); 58 + if (c1 != c2) return c1 < c2; 59 + s1++; 60 + s2++; 61 + } 62 + } 63 + 64 + // One string is prefix of other 65 + return *s1 == '\0' && *s2 != '\0'; 24 66 }); 25 67 } 26 68