Always sort ignoring word case

This commit is contained in:
Artem Chepurnoy 2024-01-15 10:16:48 +02:00
parent 61b64ba555
commit 2113847162
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
12 changed files with 51 additions and 14 deletions

View File

@ -0,0 +1,26 @@
package com.artemchep.keyguard.common.util
class StringComparatorIgnoreCase<T>(
private val descending: Boolean = false,
private val getter: (T) -> String?,
) : Comparator<T> {
override fun compare(aHolder: T, bHolder: T): Int {
val a = getter(aHolder)
val b = getter(bHolder)
var r = internalCompare(a, b)
// Reverse the comparison result,
// if needed.
if (descending) {
r *= -1
}
return r
}
private fun internalCompare(a: String?, b: String?): Int {
if (a === b) return 0
if (a == null) return -1
if (b == null) return 1
return a.compareTo(b, ignoreCase = true)
}
}

View File

@ -30,6 +30,7 @@ import com.artemchep.keyguard.common.usecase.GetFolders
import com.artemchep.keyguard.common.usecase.GetOrganizations import com.artemchep.keyguard.common.usecase.GetOrganizations
import com.artemchep.keyguard.common.usecase.GetProfiles import com.artemchep.keyguard.common.usecase.GetProfiles
import com.artemchep.keyguard.common.usecase.RemoveAttachment import com.artemchep.keyguard.common.usecase.RemoveAttachment
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.flow.foldAsList import com.artemchep.keyguard.common.util.flow.foldAsList
import com.artemchep.keyguard.feature.attachments.model.AttachmentItem import com.artemchep.keyguard.feature.attachments.model.AttachmentItem
import com.artemchep.keyguard.feature.attachments.util.createAttachmentItem import com.artemchep.keyguard.feature.attachments.util.createAttachmentItem
@ -239,7 +240,7 @@ fun produceAttachmentsScreenState(
.map { list -> .map { list ->
list list
.filterNotNull() .filterNotNull()
.sortedBy { it.item.name } .sortedWith(StringComparatorIgnoreCase { it.item.name })
} }
} }
.shareInScreenScope() .shareInScreenScope()

View File

@ -9,6 +9,7 @@ import arrow.core.partially1
import com.artemchep.keyguard.common.model.Loadable import com.artemchep.keyguard.common.model.Loadable
import com.artemchep.keyguard.common.usecase.GetFolders import com.artemchep.keyguard.common.usecase.GetFolders
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.feature.auth.common.TextFieldModel2 import com.artemchep.keyguard.feature.auth.common.TextFieldModel2
import com.artemchep.keyguard.feature.auth.common.Validated import com.artemchep.keyguard.feature.auth.common.Validated
import com.artemchep.keyguard.feature.auth.common.util.validatedTitle import com.artemchep.keyguard.feature.auth.common.util.validatedTitle
@ -130,7 +131,7 @@ fun folderConfirmationState(
.map { folders -> .map { folders ->
val items = folders val items = folders
.filter { it.accountId == args.accountId.id } .filter { it.accountId == args.accountId.id }
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { folder -> .map { folder ->
val folderEnabled = folder.id !in args.blacklistedFolderIds val folderEnabled = folder.id !in args.blacklistedFolderIds
val folderInfo = FolderVariant.FolderInfo.Id( val folderInfo = FolderVariant.FolderInfo.Id(

View File

@ -21,6 +21,7 @@ import com.artemchep.keyguard.common.usecase.GetFolders
import com.artemchep.keyguard.common.usecase.GetOrganizations import com.artemchep.keyguard.common.usecase.GetOrganizations
import com.artemchep.keyguard.common.usecase.GetProfiles import com.artemchep.keyguard.common.usecase.GetProfiles
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.contains import com.artemchep.keyguard.common.util.contains
import com.artemchep.keyguard.feature.auth.common.TextFieldModel2 import com.artemchep.keyguard.feature.auth.common.TextFieldModel2
import com.artemchep.keyguard.feature.auth.common.Validated import com.artemchep.keyguard.feature.auth.common.Validated
@ -230,7 +231,7 @@ fun organizationConfirmationState(
accountsFlow, accountsFlow,
) { organizations, accounts -> ) { organizations, accounts ->
organizations organizations
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { organization -> .map { organization ->
val enabled = organization.id !in args.blacklistedOrganizationIds val enabled = organization.id !in args.blacklistedOrganizationIds
OrganizationVariant( OrganizationVariant(
@ -274,7 +275,7 @@ fun organizationConfirmationState(
accountsFlow, accountsFlow,
) { folders, accounts -> ) { folders, accounts ->
folders folders
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { folder -> .map { folder ->
val enabled = folder.id !in args.blacklistedFolderIds val enabled = folder.id !in args.blacklistedFolderIds
FolderVariant( FolderVariant(

View File

@ -15,6 +15,7 @@ import com.artemchep.keyguard.common.service.relays.api.EmailRelay
import com.artemchep.keyguard.common.usecase.AddEmailRelay import com.artemchep.keyguard.common.usecase.AddEmailRelay
import com.artemchep.keyguard.common.usecase.GetEmailRelays import com.artemchep.keyguard.common.usecase.GetEmailRelays
import com.artemchep.keyguard.common.usecase.RemoveEmailRelayById import com.artemchep.keyguard.common.usecase.RemoveEmailRelayById
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.flow.persistingStateIn import com.artemchep.keyguard.common.util.flow.persistingStateIn
import com.artemchep.keyguard.feature.attachments.SelectableItemState import com.artemchep.keyguard.feature.attachments.SelectableItemState
import com.artemchep.keyguard.feature.attachments.SelectableItemStateRaw import com.artemchep.keyguard.feature.attachments.SelectableItemStateRaw
@ -200,7 +201,7 @@ fun produceEmailRelayListState(
.partially1(emailRelay), .partially1(emailRelay),
) )
} }
.sortedBy { it.title } .sortedWith(StringComparatorIgnoreCase { it.title })
.toImmutableList() .toImmutableList()
val itemsRawFlow = getEmailRelays() val itemsRawFlow = getEmailRelays()

View File

@ -19,6 +19,7 @@ import com.artemchep.keyguard.common.usecase.QueueSyncById
import com.artemchep.keyguard.common.usecase.RemoveAccountById import com.artemchep.keyguard.common.usecase.RemoveAccountById
import com.artemchep.keyguard.common.usecase.SupervisorRead import com.artemchep.keyguard.common.usecase.SupervisorRead
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.flow.foldAsList import com.artemchep.keyguard.common.util.flow.foldAsList
import com.artemchep.keyguard.feature.auth.AccountViewRoute import com.artemchep.keyguard.feature.auth.AccountViewRoute
import com.artemchep.keyguard.feature.confirmation.createConfirmationDialogIntent import com.artemchep.keyguard.feature.confirmation.createConfirmationDialogIntent
@ -287,7 +288,7 @@ fun accountListScreenState(
.foldAsList() .foldAsList()
.map { items -> .map { items ->
items items
.sortedBy { it.text } .sortedWith(StringComparatorIgnoreCase { it.text })
} }
combine( combine(

View File

@ -88,6 +88,7 @@ import com.artemchep.keyguard.common.usecase.GetOrganizations
import com.artemchep.keyguard.common.usecase.GetProfiles import com.artemchep.keyguard.common.usecase.GetProfiles
import com.artemchep.keyguard.common.usecase.GetTotpCode import com.artemchep.keyguard.common.usecase.GetTotpCode
import com.artemchep.keyguard.common.usecase.ShowMessage import com.artemchep.keyguard.common.usecase.ShowMessage
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.flow.EventFlow import com.artemchep.keyguard.common.util.flow.EventFlow
import com.artemchep.keyguard.common.util.flow.combineToList import com.artemchep.keyguard.common.util.flow.combineToList
import com.artemchep.keyguard.common.util.flow.foldAsList import com.artemchep.keyguard.common.util.flow.foldAsList
@ -1965,7 +1966,7 @@ private suspend fun RememberStateFlowScope.produceOwnershipFlow(
} }
val selectedCollections = collections val selectedCollections = collections
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.filter { it.id in collectionIds } .filter { it.id in collectionIds }
val el = AddState.SaveToElement( val el = AddState.SaveToElement(
readOnly = ro, readOnly = ro,

View File

@ -19,6 +19,7 @@ import com.artemchep.keyguard.common.usecase.GetFolders
import com.artemchep.keyguard.common.usecase.MergeFolderById import com.artemchep.keyguard.common.usecase.MergeFolderById
import com.artemchep.keyguard.common.usecase.RemoveFolderById import com.artemchep.keyguard.common.usecase.RemoveFolderById
import com.artemchep.keyguard.common.usecase.RenameFolderById import com.artemchep.keyguard.common.usecase.RenameFolderById
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.core.store.bitwarden.exists import com.artemchep.keyguard.core.store.bitwarden.exists
import com.artemchep.keyguard.feature.confirmation.ConfirmationResult import com.artemchep.keyguard.feature.confirmation.ConfirmationResult
import com.artemchep.keyguard.feature.confirmation.ConfirmationRoute import com.artemchep.keyguard.feature.confirmation.ConfirmationRoute
@ -189,7 +190,7 @@ fun foldersScreenState(
translate(Res.strings.folder_action_change_name_title) translate(Res.strings.folder_action_change_name_title)
}, },
items = folders items = folders
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { folder -> .map { folder ->
ConfirmationRoute.Args.Item.StringItem( ConfirmationRoute.Args.Item.StringItem(
key = folder.id, key = folder.id,

View File

@ -27,6 +27,7 @@ import com.artemchep.keyguard.common.model.DSecret
import com.artemchep.keyguard.common.model.iconImageVector import com.artemchep.keyguard.common.model.iconImageVector
import com.artemchep.keyguard.common.model.titleH import com.artemchep.keyguard.common.model.titleH
import com.artemchep.keyguard.common.usecase.GetFolderTree import com.artemchep.keyguard.common.usecase.GetFolderTree
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.feature.home.vault.component.rememberSecretAccentColor import com.artemchep.keyguard.feature.home.vault.component.rememberSecretAccentColor
import com.artemchep.keyguard.feature.home.vault.model.FilterItem import com.artemchep.keyguard.feature.home.vault.model.FilterItem
import com.artemchep.keyguard.feature.home.vault.search.filter.FilterHolder import com.artemchep.keyguard.feature.home.vault.search.filter.FilterHolder
@ -560,7 +561,7 @@ suspend fun <
title = name, title = name,
) )
} }
.sortedBy { it.title } .sortedWith(StringComparatorIgnoreCase { it.title })
.toList() + .toList() +
createCollectionFilterAction( createCollectionFilterAction(
collectionIds = setOfNull, collectionIds = setOfNull,
@ -602,7 +603,7 @@ suspend fun <
title = name, title = name,
) )
} }
.sortedBy { it.title } .sortedWith(StringComparatorIgnoreCase { it.title })
.toList() + .toList() +
createOrganizationFilterAction( createOrganizationFilterAction(
organizationIds = setOfNull, organizationIds = setOfNull,

View File

@ -60,6 +60,7 @@ import com.artemchep.keyguard.common.usecase.PasskeyTargetCheck
import com.artemchep.keyguard.common.usecase.QueueSyncAll import com.artemchep.keyguard.common.usecase.QueueSyncAll
import com.artemchep.keyguard.common.usecase.RenameFolderById import com.artemchep.keyguard.common.usecase.RenameFolderById
import com.artemchep.keyguard.common.usecase.SupervisorRead import com.artemchep.keyguard.common.usecase.SupervisorRead
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.flow.EventFlow import com.artemchep.keyguard.common.util.flow.EventFlow
import com.artemchep.keyguard.common.util.flow.persistingStateIn import com.artemchep.keyguard.common.util.flow.persistingStateIn
import com.artemchep.keyguard.feature.attachments.AttachmentsRoute import com.artemchep.keyguard.feature.attachments.AttachmentsRoute
@ -284,7 +285,7 @@ fun vaultListScreenState(
icon = icon(Icons.Outlined.Edit), icon = icon(Icons.Outlined.Edit),
title = "Change folder name", title = "Change folder name",
items = folders items = folders
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { folder -> .map { folder ->
ConfirmationRoute.Args.Item.StringItem( ConfirmationRoute.Args.Item.StringItem(
key = folder.id, key = folder.id,

View File

@ -133,6 +133,7 @@ import com.artemchep.keyguard.common.usecase.RestoreCipherById
import com.artemchep.keyguard.common.usecase.RetryCipher import com.artemchep.keyguard.common.usecase.RetryCipher
import com.artemchep.keyguard.common.usecase.TrashCipherById import com.artemchep.keyguard.common.usecase.TrashCipherById
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.common.util.flow.persistingStateIn import com.artemchep.keyguard.common.util.flow.persistingStateIn
import com.artemchep.keyguard.core.store.bitwarden.canRetry import com.artemchep.keyguard.core.store.bitwarden.canRetry
import com.artemchep.keyguard.core.store.bitwarden.expired import com.artemchep.keyguard.core.store.bitwarden.expired
@ -421,7 +422,7 @@ fun vaultViewScreenState(
collections collections
.firstOrNull { it.id == collectionId && it.accountId == accountId } .firstOrNull { it.id == collectionId && it.accountId == accountId }
} }
.sortedByDescending { it.name } .sortedWith(StringComparatorIgnoreCase(descending = true) { it.name })
} }
.distinctUntilChanged() .distinctUntilChanged()
val organizationFlow = getOrganizations() val organizationFlow = getOrganizations()

View File

@ -36,6 +36,7 @@ import com.artemchep.keyguard.common.usecase.RePromptCipherById
import com.artemchep.keyguard.common.usecase.RemoveCipherById import com.artemchep.keyguard.common.usecase.RemoveCipherById
import com.artemchep.keyguard.common.usecase.RestoreCipherById import com.artemchep.keyguard.common.usecase.RestoreCipherById
import com.artemchep.keyguard.common.usecase.TrashCipherById import com.artemchep.keyguard.common.usecase.TrashCipherById
import com.artemchep.keyguard.common.util.StringComparatorIgnoreCase
import com.artemchep.keyguard.feature.confirmation.ConfirmationResult import com.artemchep.keyguard.feature.confirmation.ConfirmationResult
import com.artemchep.keyguard.feature.confirmation.ConfirmationRoute import com.artemchep.keyguard.feature.confirmation.ConfirmationRoute
import com.artemchep.keyguard.feature.confirmation.folder.FolderConfirmationResult import com.artemchep.keyguard.feature.confirmation.folder.FolderConfirmationResult
@ -371,7 +372,7 @@ fun RememberStateFlowScope.cipherChangeNameAction(
before?.invoke() before?.invoke()
val items = ciphers val items = ciphers
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { cipher -> .map { cipher ->
ConfirmationRoute.Args.Item.StringItem( ConfirmationRoute.Args.Item.StringItem(
key = cipher.id, key = cipher.id,
@ -444,7 +445,7 @@ fun RememberStateFlowScope.cipherChangePasswordAction(
val items = ciphers val items = ciphers
.filter { it.type == DSecret.Type.Login } .filter { it.type == DSecret.Type.Login }
.sortedBy { it.name } .sortedWith(StringComparatorIgnoreCase { it.name })
.map { cipher -> .map { cipher ->
ConfirmationRoute.Args.Item.StringItem( ConfirmationRoute.Args.Item.StringItem(
key = cipher.id, key = cipher.id,