diff --git a/app/src/main/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContent.kt b/app/src/main/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContent.kt index b84dc76108c..57007fae7aa 100644 --- a/app/src/main/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContent.kt +++ b/app/src/main/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContent.kt @@ -150,4 +150,6 @@ data class ConversationSheetContent( fun canAddToFavourite(): Boolean = (conversationTypeDetail is ConversationTypeDetail.Private && conversationTypeDetail.blockingState != BlockingState.BLOCKED) || conversationTypeDetail is ConversationTypeDetail.Group + + fun isAbandonedOneOnOneConversation(participantsCount: Int): Boolean = title.isEmpty() && participantsCount == 1 } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/GroupConversationDetailsScreen.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/GroupConversationDetailsScreen.kt index ef8a870b355..97c4169a94f 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/GroupConversationDetailsScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/GroupConversationDetailsScreen.kt @@ -239,7 +239,11 @@ fun GroupConversationDetailsScreen( }, isLoading = viewModel.requestInProgress, onSearchConversationMessagesClick = onSearchConversationMessagesClick, - onConversationMediaClick = onConversationMediaClick + onConversationMediaClick = onConversationMediaClick, + isAbandonedOneOnOneConversation = viewModel.conversationSheetContent?.isAbandonedOneOnOneConversation( + viewModel.groupParticipantsState.data.allCount + ) ?: false + ) val tryAgainSnackBarMessage = stringResource(id = R.string.error_unknown_message) @@ -279,6 +283,7 @@ private fun GroupConversationDetailsContent( onDeleteGroup: (GroupDialogState) -> Unit, groupParticipantsState: GroupConversationParticipantsState, isLoading: Boolean, + isAbandonedOneOnOneConversation: Boolean, onSearchConversationMessagesClick: () -> Unit, onConversationMediaClick: () -> Unit ) { @@ -385,7 +390,7 @@ private fun GroupConversationDetailsContent( } GroupConversationDetailsTabItem.PARTICIPANTS -> { - if (groupParticipantsState.addParticipantsEnabled) { + if (groupParticipantsState.addParticipantsEnabled && !isAbandonedOneOnOneConversation) { Box(modifier = Modifier.padding(MaterialTheme.wireDimensions.spacing16x)) { WirePrimaryButton( text = stringResource(R.string.conversation_details_group_participants_add), @@ -601,7 +606,8 @@ fun PreviewGroupConversationDetails() { onEditSelfDeletingMessages = {}, onEditGuestAccess = {}, onSearchConversationMessagesClick = {}, - onConversationMediaClick = {} + onConversationMediaClick = {}, + isAbandonedOneOnOneConversation = false ) } } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/GroupConversationParticipants.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/GroupConversationParticipants.kt index 88eda234d55..ac5f136e732 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/GroupConversationParticipants.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/GroupConversationParticipants.kt @@ -55,8 +55,8 @@ import com.wire.kalium.logic.data.user.SupportedProtocol fun GroupConversationParticipants( onProfilePressed: (UIParticipant) -> Unit, groupParticipantsState: GroupConversationParticipantsState, - modifier: Modifier = Modifier, - lazyListState: LazyListState = rememberLazyListState() + lazyListState: LazyListState, + modifier: Modifier = Modifier ) { val context = LocalContext.current Column(modifier = modifier) { @@ -125,7 +125,13 @@ fun MLSProgressIndicator( @PreviewMultipleThemes @Composable fun PreviewGroupConversationParticipants() = WireTheme { - GroupConversationParticipants({}, GroupConversationParticipantsState.PREVIEW) + GroupConversationParticipants({}, GroupConversationParticipantsState.PREVIEW, rememberLazyListState()) +} + +@PreviewMultipleThemes +@Composable +fun PreviewGroupConversationParticipantsAdandonedOneOnOne() = WireTheme { + GroupConversationParticipants({}, GroupConversationParticipantsState.PREVIEW, rememberLazyListState()) } @PreviewMultipleThemes diff --git a/app/src/test/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContentTest.kt b/app/src/test/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContentTest.kt new file mode 100644 index 00000000000..09f6b2160ab --- /dev/null +++ b/app/src/test/kotlin/com/wire/android/ui/common/bottomsheet/conversation/ConversationSheetContentTest.kt @@ -0,0 +1,94 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.android.ui.common.bottomsheet.conversation + +import com.wire.android.ui.home.conversations.details.GroupConversationDetailsViewModelTest.Companion.testGroup +import com.wire.kalium.logic.data.conversation.Conversation +import com.wire.kalium.logic.data.id.TeamId +import kotlinx.coroutines.test.runTest +import org.amshove.kluent.internal.assertEquals +import org.junit.jupiter.api.Test + +class ConversationSheetContentTest { + + @Test + fun givenTitleIsEmptyAndTheGroupSizeIsOne_whenCallingIsTheGroupAbandoned_returnsTrue() = runTest { + val details = testGroup.copy(conversation = testGroup.conversation.copy(teamId = TeamId("team_id"))) + + val givenConversationSheetContent = ConversationSheetContent( + title = "", + conversationId = details.conversation.id, + mutingConversationState = details.conversation.mutedStatus, + conversationTypeDetail = ConversationTypeDetail.Group(details.conversation.id, details.isSelfUserCreator), + selfRole = Conversation.Member.Role.Member, + isTeamConversation = details.conversation.isTeamGroup(), + isArchived = false, + protocol = Conversation.ProtocolInfo.Proteus, + mlsVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, + proteusVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, + isUnderLegalHold = false + ) + val givenParticipantsCount = 1 + + assertEquals(true, givenConversationSheetContent.isAbandonedOneOnOneConversation(givenParticipantsCount)) + } + + @Test + fun givenTitleIsEmptyAndTheGroupSizeIsGtOne_whenCallingIsTheGroupAbandoned_returnsFalse() = runTest { + val details = testGroup.copy(conversation = testGroup.conversation.copy(teamId = TeamId("team_id"))) + + val givenConversationSheetContent = ConversationSheetContent( + title = "", + conversationId = details.conversation.id, + mutingConversationState = details.conversation.mutedStatus, + conversationTypeDetail = ConversationTypeDetail.Group(details.conversation.id, details.isSelfUserCreator), + selfRole = Conversation.Member.Role.Member, + isTeamConversation = details.conversation.isTeamGroup(), + isArchived = false, + protocol = Conversation.ProtocolInfo.Proteus, + mlsVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, + proteusVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, + isUnderLegalHold = false + ) + val givenParticipantsCount = 3 + + assertEquals(false, givenConversationSheetContent.isAbandonedOneOnOneConversation(givenParticipantsCount)) + } + + @Test + fun givenTitleIsNotEmptyAndTheGroupSizeIsOne_whenCallingIsTheGroupAbandoned_returnsFalse() = runTest { + val details = testGroup.copy(conversation = testGroup.conversation.copy(teamId = TeamId("team_id"))) + + val givenConversationSheetContent = ConversationSheetContent( + title = "notEmpty", + conversationId = details.conversation.id, + mutingConversationState = details.conversation.mutedStatus, + conversationTypeDetail = ConversationTypeDetail.Group(details.conversation.id, details.isSelfUserCreator), + selfRole = Conversation.Member.Role.Member, + isTeamConversation = details.conversation.isTeamGroup(), + isArchived = false, + protocol = Conversation.ProtocolInfo.Proteus, + mlsVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, + proteusVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, + isUnderLegalHold = false + ) + val givenParticipantsCount = 3 + + assertEquals(false, givenConversationSheetContent.isAbandonedOneOnOneConversation(givenParticipantsCount)) + } +}