improve sorting for new conversation name

sort users so original users come first when creating new conversation from 1:1 conversation

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2025-04-14 11:57:15 +02:00
parent b0da7243e5
commit f34968c886
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
3 changed files with 48 additions and 12 deletions

View File

@ -159,7 +159,7 @@ class ConversationInfoActivity :
private val addParticipantsResult = registerForActivityResult( private val addParticipantsResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult() ActivityResultContracts.StartActivityForResult()
) { ) { it ->
executeIfResultOk(it) { intent -> executeIfResultOk(it) { intent ->
val selectedAutocompleteUsers = val selectedAutocompleteUsers =
intent?.getParcelableArrayListExtraProvider<AutocompleteUser>("selectedParticipants") intent?.getParcelableArrayListExtraProvider<AutocompleteUser>("selectedParticipants")
@ -168,6 +168,7 @@ class ConversationInfoActivity :
if (startGroupChat) { if (startGroupChat) {
viewModel.createRoomFromOneToOne( viewModel.createRoomFromOneToOne(
conversationUser, conversationUser,
userItems.map { it.model },
selectedAutocompleteUsers, selectedAutocompleteUsers,
conversationToken conversationToken
) )
@ -237,6 +238,7 @@ class ConversationInfoActivity :
initObservers() initObservers()
} }
@Suppress("Detekt.LongMethod")
private fun initObservers() { private fun initObservers() {
initViewStateObserver() initViewStateObserver()

View File

@ -22,6 +22,7 @@ import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import com.nextcloud.talk.models.json.capabilities.SpreedCapability import com.nextcloud.talk.models.json.capabilities.SpreedCapability
import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.models.json.participants.Participant.ActorType.CIRCLES import com.nextcloud.talk.models.json.participants.Participant.ActorType.CIRCLES
import com.nextcloud.talk.models.json.participants.Participant.ActorType.EMAILS import com.nextcloud.talk.models.json.participants.Participant.ActorType.EMAILS
import com.nextcloud.talk.models.json.participants.Participant.ActorType.FEDERATED import com.nextcloud.talk.models.json.participants.Participant.ActorType.FEDERATED
@ -135,7 +136,12 @@ class ConversationInfoViewModel @Inject constructor(
} }
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
fun createRoomFromOneToOne(user: User, autocompleteUsers: List<AutocompleteUser>, roomToken: String) { fun createRoomFromOneToOne(
user: User,
userItems: List<Participant>,
autocompleteUsers: List<AutocompleteUser>,
roomToken: String
) {
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, 1)) val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, 1))
val url = getUrlForRooms(apiVersion, user.baseUrl!!) val url = getUrlForRooms(apiVersion, user.baseUrl!!)
val credentials = ApiUtils.getCredentials(user.username, user.token)!! val credentials = ApiUtils.getCredentials(user.username, user.token)!!
@ -143,7 +149,10 @@ class ConversationInfoViewModel @Inject constructor(
val participantsBody = convertAutocompleteUserToParticipant(autocompleteUsers) val participantsBody = convertAutocompleteUserToParticipant(autocompleteUsers)
val body = CreateRoomRequest( val body = CreateRoomRequest(
roomName = createConversationNameByParticipants(autocompleteUsers), roomName = createConversationNameByParticipants(
userItems.map { it.displayName },
autocompleteUsers.map { it.label }
),
roomType = GROUP_CONVERSATION_TYPE, roomType = GROUP_CONVERSATION_TYPE,
readOnly = 0, readOnly = 0,
listable = 1, listable = 1,
@ -172,15 +181,6 @@ class ConversationInfoViewModel @Inject constructor(
} }
} }
private fun createConversationNameByParticipants(autocompleteUsers: List<AutocompleteUser>): String {
val conversationName = autocompleteUsers
.sortedBy { it.label?.lowercase() }
.mapNotNull { it.label }
.joinToString(NEW_CONVERSATION_PARTICIPANTS_SEPARATOR)
return DisplayUtils.ellipsize(conversationName, MAX_ROOM_NAME_LENGTH)
}
private fun convertAutocompleteUserToParticipant(autocompleteUsers: List<AutocompleteUser>): Participants { private fun convertAutocompleteUserToParticipant(autocompleteUsers: List<AutocompleteUser>): Participants {
val participants = Participants() val participants = Participants()
@ -362,6 +362,22 @@ class ConversationInfoViewModel @Inject constructor(
private const val EXTENDED_CONVERSATION = "extended_conversation" private const val EXTENDED_CONVERSATION = "extended_conversation"
private const val GROUP_CONVERSATION_TYPE = "2" private const val GROUP_CONVERSATION_TYPE = "2"
private const val MAX_ROOM_NAME_LENGTH = 255 private const val MAX_ROOM_NAME_LENGTH = 255
fun createConversationNameByParticipants(
originalParticipants: List<String?>,
allParticipants: List<String?>
): String {
fun List<String?>.sortedJoined() =
sortedBy { it?.lowercase() }
.joinToString(NEW_CONVERSATION_PARTICIPANTS_SEPARATOR)
val addedParticipants = allParticipants - originalParticipants.toSet()
val conversationName = originalParticipants.mapNotNull { it }.sortedJoined() +
NEW_CONVERSATION_PARTICIPANTS_SEPARATOR +
addedParticipants.mapNotNull { it }.sortedJoined()
return DisplayUtils.ellipsize(conversationName, MAX_ROOM_NAME_LENGTH)
}
} }
sealed class ClearChatHistoryViewState { sealed class ClearChatHistoryViewState {

View File

@ -0,0 +1,18 @@
package com.nextcloud.talk.conversationinfo.viewmodel
import org.junit.Test
import org.junit.Assert.assertEquals
class ConversationInfoViewModelTest {
@Test
fun `createConversationNameByParticipants should combine names correctly`() {
val original = listOf("Dave", null, "Charlie")
val all = listOf("Bob", "Charlie", "Dave", "Alice", null, "Simon")
val expectedName = "Charlie, Dave, Alice, Bob, Simon"
val result = ConversationInfoViewModel.createConversationNameByParticipants(original, all)
assertEquals(expectedName, result)
}
}