mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-05 12:54:35 +00:00
Merge pull request #7536 from hayaksi1/fix/3434-mention-suggestion-ranking
Rank the mention suggestions by how well they match what was typed
This commit is contained in:
+14
-1
@@ -115,9 +115,10 @@ class SuggestionsProcessor(
|
|||||||
.filterUpTo(MAX_BATCH_ITEMS) { member ->
|
.filterUpTo(MAX_BATCH_ITEMS) { member ->
|
||||||
isJoinedMemberAndNotSelf(member) && memberMatchesQuery(member, query)
|
isJoinedMemberAndNotSelf(member) && memberMatchesQuery(member, query)
|
||||||
}
|
}
|
||||||
|
.sortedBy { member -> matchRank(member, query) }
|
||||||
.map(ResolvedSuggestion::Member)
|
.map(ResolvedSuggestion::Member)
|
||||||
|
|
||||||
if ("room".contains(query) && canSendRoomMention) {
|
if ("room".startsWith(query, ignoreCase = true) && canSendRoomMention) {
|
||||||
listOf(ResolvedSuggestion.AtRoom) + matchingMembers
|
listOf(ResolvedSuggestion.AtRoom) + matchingMembers
|
||||||
} else {
|
} else {
|
||||||
matchingMembers
|
matchingMembers
|
||||||
@@ -125,6 +126,18 @@ class SuggestionsProcessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Members whose display name starts with the query come first, then members whose user id
|
||||||
|
* localpart starts with it, then the remaining matches on any other part of the name or id.
|
||||||
|
*/
|
||||||
|
private fun matchRank(member: RoomMember, query: String): Int {
|
||||||
|
return when {
|
||||||
|
member.displayName?.startsWith(query, ignoreCase = true) == true -> 0
|
||||||
|
member.userId.extractedDisplayName.startsWith(query, ignoreCase = true) -> 1
|
||||||
|
else -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// We don't want to retrieve thousands of members
|
// We don't want to retrieve thousands of members
|
||||||
private const val MAX_BATCH_ITEMS = 100
|
private const val MAX_BATCH_ITEMS = 100
|
||||||
|
|||||||
+42
@@ -383,6 +383,48 @@ class SuggestionsProcessorTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `processing Mention suggestion returns the members matching the start of the query first`() = runTest {
|
||||||
|
val matchingOnAnyPart = aRoomMember(userId = UserId("@carol:server.org"), displayName = "Not Alice")
|
||||||
|
val matchingOnUserIdStart = aRoomMember(userId = UserId("@alicia:server.org"), displayName = null)
|
||||||
|
val matchingOnDisplayNameStart = aRoomMember(userId = UserId("@zoe:server.org"), displayName = "Alice")
|
||||||
|
val result = suggestionsProcessor.process(
|
||||||
|
suggestion = aMentionSuggestion("ali"),
|
||||||
|
roomMembersState = RoomMembersState.Ready(
|
||||||
|
persistentListOf(matchingOnAnyPart, matchingOnUserIdStart, matchingOnDisplayNameStart)
|
||||||
|
),
|
||||||
|
roomAliasSuggestions = emptyList(),
|
||||||
|
currentUserId = A_USER_ID_2,
|
||||||
|
canSendRoomMention = { false },
|
||||||
|
isInThread = false,
|
||||||
|
)
|
||||||
|
assertThat(result).isEqualTo(
|
||||||
|
listOf(
|
||||||
|
ResolvedSuggestion.Member(matchingOnDisplayNameStart),
|
||||||
|
ResolvedSuggestion.Member(matchingOnUserIdStart),
|
||||||
|
ResolvedSuggestion.Member(matchingOnAnyPart),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `processing Mention suggestion returns room ignoring the case of the query`() = runTest {
|
||||||
|
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "alice")
|
||||||
|
val result = suggestionsProcessor.process(
|
||||||
|
suggestion = aMentionSuggestion("RO"),
|
||||||
|
roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
|
||||||
|
roomAliasSuggestions = emptyList(),
|
||||||
|
currentUserId = A_USER_ID_2,
|
||||||
|
canSendRoomMention = { true },
|
||||||
|
isInThread = false,
|
||||||
|
)
|
||||||
|
assertThat(result).isEqualTo(
|
||||||
|
listOf(
|
||||||
|
ResolvedSuggestion.AtRoom,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `processing Mention suggestion with return matching display name but not room if not allowed`() = runTest {
|
fun `processing Mention suggestion with return matching display name but not room if not allowed`() = runTest {
|
||||||
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "ro")
|
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "ro")
|
||||||
|
|||||||
Reference in New Issue
Block a user