diff --git a/changelog/unreleased/4760 b/changelog/unreleased/4760 new file mode 100644 index 00000000000..0d67c43f2ff --- /dev/null +++ b/changelog/unreleased/4760 @@ -0,0 +1,6 @@ +Bugfix: Fix alphabetical ordering when sorting files by name + +Use locale-aware collation for file sorting by name to handle accented characters correctly. + +https://github.com/owncloud/android/issues/4760 +https://github.com/owncloud/android/pull/4785 \ No newline at end of file diff --git a/owncloudApp/src/main/java/com/owncloud/android/utils/SortFilesUtils.kt b/owncloudApp/src/main/java/com/owncloud/android/utils/SortFilesUtils.kt index 063db23cecc..a8b9ce5b7b7 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/utils/SortFilesUtils.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/utils/SortFilesUtils.kt @@ -20,6 +20,8 @@ package com.owncloud.android.utils import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.presentation.files.SortType +import java.text.Collator +import java.util.Locale class SortFilesUtils { fun sortFiles( @@ -34,12 +36,20 @@ class SortFilesUtils { } private fun sortByName(listOfFiles: List, ascending: Boolean): List { - val newListOfFiles = - if (ascending) listOfFiles.sortedBy { it.fileName.lowercase() } - else listOfFiles.sortedByDescending { it.fileName.lowercase() } + val collator = Collator.getInstance(Locale("en", "US")).apply { + strength = Collator.PRIMARY // Ignore accents and case + } + + val comparator = compareByDescending { it.isFolder } + .thenComparator { a, b -> + if (ascending) { + collator.compare(a.fileName, b.fileName) + } else { + collator.compare(b.fileName, a.fileName) + } + } - // Show first the folders when sorting by name - return newListOfFiles.sortedByDescending { it.isFolder } + return listOfFiles.sortedWith(comparator) } private fun sortBySize(listOfFiles: List, ascending: Boolean): List = diff --git a/owncloudDomain/src/main/java/com/owncloud/android/domain/files/usecases/SortFilesWithSyncInfoUseCase.kt b/owncloudDomain/src/main/java/com/owncloud/android/domain/files/usecases/SortFilesWithSyncInfoUseCase.kt index 0a5f9080b87..d8d591e6d04 100644 --- a/owncloudDomain/src/main/java/com/owncloud/android/domain/files/usecases/SortFilesWithSyncInfoUseCase.kt +++ b/owncloudDomain/src/main/java/com/owncloud/android/domain/files/usecases/SortFilesWithSyncInfoUseCase.kt @@ -22,6 +22,8 @@ package com.owncloud.android.domain.files.usecases import com.owncloud.android.domain.BaseUseCase import com.owncloud.android.domain.files.model.OCFileWithSyncInfo +import java.text.Collator +import java.util.Locale class SortFilesWithSyncInfoUseCase : BaseUseCase, SortFilesWithSyncInfoUseCase.Params>() { @@ -33,12 +35,20 @@ class SortFilesWithSyncInfoUseCase : BaseUseCase, SortF } private fun sortByName(listOfFiles: List, ascending: Boolean): List { - val newListOfFiles = - if (ascending) listOfFiles.sortedBy { it.file.fileName.lowercase() } - else listOfFiles.sortedByDescending { it.file.fileName.lowercase() } + val collator = Collator.getInstance(Locale("en", "US")).apply { + strength = Collator.PRIMARY // Ignore accents and case + } + + val comparator = compareByDescending { it.file.isFolder } + .thenComparator { a, b -> + if (ascending) { + collator.compare(a.file.fileName, b.file.fileName) + } else { + collator.compare(b.file.fileName, a.file.fileName) + } + } - // Show first the folders when sorting by name - return newListOfFiles.sortedByDescending { it.file.isFolder } + return listOfFiles.sortedWith(comparator) } private fun sortBySize(listOfFiles: List, ascending: Boolean): List =