From e1434dfe21a08ce0dd7ebb70404ef3fc68587b4e Mon Sep 17 00:00:00 2001 From: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:25:55 -0400 Subject: [PATCH] [PM-25327] Display default user collections first (#5810) --- .../vault/repository/VaultRepositoryImpl.kt | 3 ++- .../util/VaultSdkCollectionExtensions.kt | 21 ++++++++++++------- .../util/VaultSdkCollectionExtensionsTest.kt | 16 +++++++++----- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt b/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt index d61f53bc8a..245acac2fb 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt @@ -82,6 +82,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.UpdateSendResult import com.x8bit.bitwarden.data.vault.repository.model.VaultData import com.x8bit.bitwarden.data.vault.repository.model.VaultUnlockResult import com.x8bit.bitwarden.data.vault.repository.util.sortAlphabetically +import com.x8bit.bitwarden.data.vault.repository.util.sortAlphabeticallyByType import com.x8bit.bitwarden.data.vault.repository.util.toDomainsData import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkFolder import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkSend @@ -1167,7 +1168,7 @@ class VaultRepositoryImpl( .fold( onSuccess = { collections -> DataState.Loaded( - collections.sortAlphabetically(), + collections.sortAlphabeticallyByType(), ) }, onFailure = { throwable -> DataState.Error(throwable) }, diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt index 827d86543e..14f5b30ef5 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt @@ -21,7 +21,7 @@ fun SyncResponseJson.Collection.toEncryptedSdkCollection(): Collection = readOnly = this.isReadOnly, manage = this.canManage ?: !this.isReadOnly, defaultUserCollectionEmail = this.defaultUserCollectionEmail, - type = this.type.toCollectionType(), + type = this.type.toSdkCollectionType(), ) /** @@ -32,14 +32,21 @@ fun List.toEncryptedSdkCollectionList(): List.sortAlphabetically(): List { +fun List.sortAlphabeticallyByType(): List { return this.sortedWith( - comparator = { collection1, collection2 -> - SpecialCharWithPrecedenceComparator.compare(collection1.name, collection2.name) - }, + // DEFAULT_USER_COLLECTION come first + comparator = compareBy { it.type != CollectionType.DEFAULT_USER_COLLECTION } + // Then sort by other CollectionType ordinals + .thenBy { it.type } + // Finally, sort by name within each group + .thenComparing( + CollectionView::name, + SpecialCharWithPrecedenceComparator, + ), ) } @@ -47,7 +54,7 @@ fun List.sortAlphabetically(): List { * Converts a [CollectionType] object to a corresponding * Bitwarden SDK [CollectionTypeJson] object. */ -fun CollectionTypeJson.toCollectionType(): CollectionType = +fun CollectionTypeJson.toSdkCollectionType(): CollectionType = when (this) { CollectionTypeJson.SHARED_COLLECTION -> CollectionType.SHARED_COLLECTION CollectionTypeJson.DEFAULT_USER_COLLECTION -> CollectionType.DEFAULT_USER_COLLECTION diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt index 27bfcc461c..639fd42bfc 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt @@ -103,7 +103,7 @@ class VaultSdkCollectionExtensionsTest { @Suppress("MaxLineLength") @Test - fun `toSortAlphabetically should sort collections by name`() { + fun `toSortAlphabetically should sort collections by type and name`() { val list = listOf( createMockCollectionView(1).copy(name = "c"), createMockCollectionView(1).copy(name = "B"), @@ -111,29 +111,35 @@ class VaultSdkCollectionExtensionsTest { createMockCollectionView(1).copy(name = "4"), createMockCollectionView(1).copy(name = "A"), createMockCollectionView(1).copy(name = "#"), - createMockCollectionView(1).copy(name = "D"), + createMockCollectionView(1).copy( + name = "D", + type = CollectionType.DEFAULT_USER_COLLECTION, + ), ) val expected = listOf( + createMockCollectionView(1).copy( + name = "D", + type = CollectionType.DEFAULT_USER_COLLECTION, + ), createMockCollectionView(1).copy(name = "#"), createMockCollectionView(1).copy(name = "4"), createMockCollectionView(1).copy(name = "A"), createMockCollectionView(1).copy(name = "B"), createMockCollectionView(1).copy(name = "c"), - createMockCollectionView(1).copy(name = "D"), createMockCollectionView(1).copy(name = "z"), ) assertEquals( expected, - list.sortAlphabetically(), + list.sortAlphabeticallyByType(), ) } @Test fun `toCollectionType should convert CollectionTypeJson to CollectionType`() { val collectionType = CollectionTypeJson.SHARED_COLLECTION - val sdkCollectionType = collectionType.toCollectionType() + val sdkCollectionType = collectionType.toSdkCollectionType() assertEquals( CollectionType.SHARED_COLLECTION, sdkCollectionType,