From 6ef9db1bdb6be99d80febc2f13b9d938334a0de8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 16 Dec 2024 16:18:15 +0100 Subject: [PATCH] Make the room filter use normalized strings. --- .../core/extensions/BasicExtensions.kt | 6 ++++++ .../matrix/api/roomlist/RoomListFilter.kt | 6 +++++- .../matrix/impl/roomlist/RoomListFilter.kt | 3 ++- .../impl/roomlist/RoomListFilterTest.kt | 20 ++++++++++++++++++- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt index 22a0c518ec..e16985a1d2 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt @@ -7,6 +7,7 @@ package io.element.android.libraries.core.extensions +import java.text.Normalizer import java.util.Locale fun Boolean.toOnOff() = if (this) "ON" else "OFF" @@ -83,3 +84,8 @@ fun String.safeCapitalize(): String { } } } + +fun String.withoutAccents(): String { + return Normalizer.normalize(this, Normalizer.Form.NFD) + .replace("\\p{Mn}+".toRegex(), "") +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt index d47e61099c..e3a6a64d46 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListFilter.kt @@ -7,6 +7,8 @@ package io.element.android.libraries.matrix.api.roomlist +import io.element.android.libraries.core.extensions.withoutAccents + sealed interface RoomListFilter { companion object { /** @@ -73,5 +75,7 @@ sealed interface RoomListFilter { */ data class NormalizedMatchRoomName( val pattern: String - ) : RoomListFilter + ) : RoomListFilter { + val normalizedPattern: String = pattern.withoutAccents() + } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt index 88458d56bb..41ef1d79a2 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt @@ -7,6 +7,7 @@ package io.element.android.libraries.matrix.impl.roomlist +import io.element.android.libraries.core.extensions.withoutAccents import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.roomlist.RoomListFilter @@ -30,7 +31,7 @@ val RoomListFilter.predicate !roomSummary.isInvited() && (roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread) } is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary -> - roomSummary.info.name.orEmpty().contains(pattern, ignoreCase = true) + roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true) } RoomListFilter.Invite -> { roomSummary: RoomSummary -> roomSummary.isInvited() diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt index abe7e17bba..870c3d196e 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt @@ -34,6 +34,9 @@ class RoomListFilterTest { private val roomToSearch = aRoomSummary( name = "Room to search" ) + private val roomWithAccent = aRoomSummary( + name = "Frédéric" + ) private val invitedRoom = aRoomSummary( currentUserMembership = CurrentUserMembership.INVITED ) @@ -45,6 +48,7 @@ class RoomListFilterTest { markedAsUnreadRoom, unreadNotificationRoom, roomToSearch, + roomWithAccent, invitedRoom ) @@ -69,7 +73,9 @@ class RoomListFilterTest { @Test fun `Room list filter group`() = runTest { val filter = RoomListFilter.Category.Group - assertThat(roomSummaries.filter(filter)).containsExactly(regularRoom, favoriteRoom, markedAsUnreadRoom, unreadNotificationRoom, roomToSearch) + assertThat(roomSummaries.filter(filter)).containsExactly( + regularRoom, favoriteRoom, markedAsUnreadRoom, unreadNotificationRoom, roomToSearch, roomWithAccent + ) } @Test @@ -96,6 +102,18 @@ class RoomListFilterTest { assertThat(roomSummaries.filter(filter)).containsExactly(roomToSearch) } + @Test + fun `Room list filter normalized match room name with accent`() = runTest { + val filter = RoomListFilter.NormalizedMatchRoomName("Fred") + assertThat(roomSummaries.filter(filter)).containsExactly(roomWithAccent) + } + + @Test + fun `Room list filter normalized match room name with accent when searching with accent`() = runTest { + val filter = RoomListFilter.NormalizedMatchRoomName("Fréd") + assertThat(roomSummaries.filter(filter)).containsExactly(roomWithAccent) + } + @Test fun `Room list filter all with one match`() = runTest { val filter = RoomListFilter.all(