mirror of
https://github.com/ProtonMail/android-mail.git
synced 2026-06-14 09:54:47 +00:00
Add Block Sender confirmation dialog
- If the sender is a contact, then the title changes to Block this contact - Implemented dialog state and reducer - Added view actions for the dialog ET-5145
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and Proton Mail.
|
||||
*
|
||||
* Proton Mail 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.
|
||||
*
|
||||
* Proton Mail 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 Proton Mail. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.protonmail.android.maildetail.presentation.model
|
||||
|
||||
import ch.protonmail.android.mailcontact.domain.model.ContactId
|
||||
|
||||
sealed interface BlockSenderDialogState {
|
||||
|
||||
object Hidden : BlockSenderDialogState
|
||||
|
||||
sealed interface Shown : BlockSenderDialogState {
|
||||
data class ShowConfirmation(
|
||||
val messageId: MessageIdUiModel?,
|
||||
val email: String,
|
||||
val contactId: ContactId?
|
||||
) : Shown
|
||||
}
|
||||
}
|
||||
+11
-2
@@ -27,6 +27,7 @@ import ch.protonmail.android.mailattachments.domain.model.OpenAttachmentIntentVa
|
||||
import ch.protonmail.android.mailcommon.presentation.model.AvatarUiModel
|
||||
import ch.protonmail.android.mailcommon.presentation.model.BottomBarEvent
|
||||
import ch.protonmail.android.mailcommon.presentation.model.BottomSheetOperation
|
||||
import ch.protonmail.android.mailcontact.domain.model.ContactId
|
||||
import ch.protonmail.android.mailconversation.domain.entity.HiddenMessagesBanner
|
||||
import ch.protonmail.android.maildetail.domain.model.OpenProtonCalendarIntentValues
|
||||
import ch.protonmail.android.maildetail.presentation.R
|
||||
@@ -39,6 +40,7 @@ import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOpe
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation.AffectingMessageBar
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation.AffectingMessages
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation.AffectingReportPhishingDialog
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation.AffectingBlockSenderDialog
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation.AffectingHiddenMessagesBanner
|
||||
import ch.protonmail.android.maillabel.domain.model.LabelId
|
||||
import ch.protonmail.android.maillabel.domain.model.SystemLabelId
|
||||
@@ -63,6 +65,8 @@ sealed interface ConversationDetailOperation {
|
||||
sealed interface AffectingHiddenMessagesBanner
|
||||
sealed interface AffectingMarkAsLegitimateDialog
|
||||
sealed interface AffectingEditScheduleMessageDialog
|
||||
sealed interface AffectingBlockSenderDialog
|
||||
|
||||
}
|
||||
|
||||
sealed interface ConversationDetailEvent : ConversationDetailOperation {
|
||||
@@ -350,8 +354,13 @@ sealed interface ConversationDetailViewAction : ConversationDetailOperation {
|
||||
|
||||
data class UnblockSender(val messageId: MessageIdUiModel?, val email: String) :
|
||||
ConversationDetailViewAction, AffectingBottomSheet
|
||||
data class BlockSender(val messageId: MessageIdUiModel?, val email: String) :
|
||||
ConversationDetailViewAction, AffectingBottomSheet
|
||||
data class BlockSender(val messageId: MessageIdUiModel?, val email: String, val contactId: ContactId?) :
|
||||
ConversationDetailViewAction, AffectingBottomSheet, AffectingBlockSenderDialog
|
||||
object BlockSenderDismissed : ConversationDetailViewAction, AffectingBlockSenderDialog
|
||||
data class BlockSenderConfirmed(
|
||||
val messageId: MessageIdUiModel?,
|
||||
val email: String
|
||||
) : ConversationDetailViewAction, AffectingBlockSenderDialog
|
||||
|
||||
data object EditScheduleSendMessageDismissed :
|
||||
ConversationDetailViewAction, AffectingEditScheduleMessageDialog
|
||||
|
||||
+4
-2
@@ -46,7 +46,8 @@ data class ConversationDetailState(
|
||||
val reportPhishingDialogState: ReportPhishingDialogState,
|
||||
val hiddenMessagesBannerState: HiddenMessagesBannerState,
|
||||
val markAsLegitimateDialogState: MarkAsLegitimateDialogState,
|
||||
val editScheduledMessageDialogState: EditScheduledMessageDialogState
|
||||
val editScheduledMessageDialogState: EditScheduledMessageDialogState,
|
||||
val blockSenderDialogState: BlockSenderDialogState
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -71,7 +72,8 @@ data class ConversationDetailState(
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+15
-7
@@ -30,6 +30,7 @@ import ch.protonmail.android.mailcommon.presentation.model.contentDescription
|
||||
import ch.protonmail.android.mailcommon.presentation.model.description
|
||||
import ch.protonmail.android.mailcommon.presentation.model.iconDrawable
|
||||
import ch.protonmail.android.mailcommon.presentation.sample.TextMessageSample
|
||||
import ch.protonmail.android.maildetail.presentation.model.BlockSenderDialogState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDeleteState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailMetadataState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailState
|
||||
@@ -97,7 +98,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
|
||||
val SuccessWithRandomMessageIds = ConversationDetailState(
|
||||
@@ -154,7 +156,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
|
||||
val FailedLoadingConversation = ConversationDetailState(
|
||||
@@ -177,7 +180,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
|
||||
val FailedLoadingMessages = ConversationDetailState(
|
||||
@@ -200,7 +204,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
|
||||
val FailedLoadingBottomBar = ConversationDetailState(
|
||||
@@ -223,7 +228,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
|
||||
val Loading = ConversationDetailState(
|
||||
@@ -246,7 +252,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
|
||||
val NotLoggedIn = ConversationDetailState(
|
||||
@@ -269,7 +276,8 @@ object ConversationDetailsPreviewData {
|
||||
reportPhishingDialogState = ReportPhishingDialogState.Hidden,
|
||||
hiddenMessagesBannerState = HiddenMessagesBannerState.Hidden,
|
||||
markAsLegitimateDialogState = MarkAsLegitimateDialogState.Hidden,
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden
|
||||
editScheduledMessageDialogState = EditScheduledMessageDialogState.Hidden,
|
||||
blockSenderDialogState = BlockSenderDialogState.Hidden
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and Proton Mail.
|
||||
*
|
||||
* Proton Mail 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.
|
||||
*
|
||||
* Proton Mail 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 Proton Mail. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.protonmail.android.maildetail.presentation.reducer
|
||||
|
||||
import ch.protonmail.android.maildetail.presentation.model.BlockSenderDialogState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailViewAction
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConversationBlockSenderDialogReducer @Inject constructor() {
|
||||
|
||||
internal fun newStateFrom(operation: ConversationDetailOperation.AffectingBlockSenderDialog) = when (operation) {
|
||||
is ConversationDetailViewAction.BlockSenderDismissed,
|
||||
is ConversationDetailViewAction.BlockSenderConfirmed -> BlockSenderDialogState.Hidden
|
||||
is ConversationDetailViewAction.BlockSender -> BlockSenderDialogState.Shown.ShowConfirmation(
|
||||
messageId = operation.messageId,
|
||||
email = operation.email,
|
||||
contactId = operation.contactId
|
||||
)
|
||||
}
|
||||
}
|
||||
+14
-1
@@ -27,6 +27,7 @@ import ch.protonmail.android.mailcommon.presentation.reducer.BottomBarReducer
|
||||
import ch.protonmail.android.maildetail.domain.model.OpenProtonCalendarIntentValues
|
||||
import ch.protonmail.android.maildetail.presentation.R
|
||||
import ch.protonmail.android.maildetail.presentation.mapper.ActionResultMapper
|
||||
import ch.protonmail.android.maildetail.presentation.model.BlockSenderDialogState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDeleteState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailEvent.ConversationBottomBarEvent
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailEvent.ConversationBottomSheetEvent
|
||||
@@ -85,6 +86,7 @@ class ConversationDetailReducer @Inject constructor(
|
||||
private val bottomSheetReducer: BottomSheetReducer,
|
||||
private val deleteDialogReducer: ConversationDeleteDialogReducer,
|
||||
private val reportPhishingDialogReducer: ConversationReportPhishingDialogReducer,
|
||||
private val blockSenderDialogReducer: ConversationBlockSenderDialogReducer,
|
||||
private val hiddenMessagesBannerReducer: HiddenMessagesBannerReducer,
|
||||
private val markAsLegitimateDialogReducer: MarkAsLegitimateDialogReducer,
|
||||
private val editScheduledMessageDialogReducer: EditScheduledMessageDialogReducer,
|
||||
@@ -114,7 +116,8 @@ class ConversationDetailReducer @Inject constructor(
|
||||
reportPhishingDialogState = currentState.toNewReportPhishingDialogState(operation),
|
||||
hiddenMessagesBannerState = currentState.toNewHiddenMessagesBannerState(operation),
|
||||
markAsLegitimateDialogState = currentState.toNewMarkAsLegitimateDialogState(operation),
|
||||
editScheduledMessageDialogState = currentState.toNewEditScheduleMessageDialogState(operation)
|
||||
editScheduledMessageDialogState = currentState.toNewEditScheduleMessageDialogState(operation),
|
||||
blockSenderDialogState = currentState.toNewBlockSenderDialogState(operation)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -380,6 +383,16 @@ class ConversationDetailReducer @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConversationDetailState.toNewBlockSenderDialogState(
|
||||
operation: ConversationDetailOperation
|
||||
): BlockSenderDialogState {
|
||||
return if (operation is ConversationDetailOperation.AffectingBlockSenderDialog) {
|
||||
blockSenderDialogReducer.newStateFrom(operation)
|
||||
} else {
|
||||
blockSenderDialogState
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConversationDetailState.toNewHiddenMessagesBannerState(
|
||||
operation: ConversationDetailOperation
|
||||
): HiddenMessagesBannerState {
|
||||
|
||||
+12
-2
@@ -116,6 +116,7 @@ import ch.protonmail.android.maildetail.presentation.model.MessageIdUiModel
|
||||
import ch.protonmail.android.maildetail.presentation.model.MoreActionsBottomSheetEntryPoint
|
||||
import ch.protonmail.android.maildetail.presentation.model.ParticipantUiModel
|
||||
import ch.protonmail.android.maildetail.presentation.previewdata.ConversationDetailsPreviewProvider
|
||||
import ch.protonmail.android.maildetail.presentation.ui.dialog.BlockSenderDialog
|
||||
import ch.protonmail.android.maildetail.presentation.ui.dialog.EditScheduleSendDialog
|
||||
import ch.protonmail.android.maildetail.presentation.ui.dialog.MarkAsLegitimateDialog
|
||||
import ch.protonmail.android.maildetail.presentation.ui.dialog.ReportPhishingDialog
|
||||
@@ -242,6 +243,13 @@ fun ConversationDetailScreen(
|
||||
onDismiss = { viewModel.submit(ConversationDetailViewAction.EditScheduleSendMessageDismissed) }
|
||||
)
|
||||
|
||||
BlockSenderDialog(
|
||||
state = state.blockSenderDialogState,
|
||||
onConfirm = { messageId, email ->
|
||||
viewModel.submit(ConversationDetailViewAction.BlockSenderConfirmed(messageId, email))
|
||||
},
|
||||
onDismiss = { viewModel.submit(ConversationDetailViewAction.BlockSenderDismissed) }
|
||||
)
|
||||
|
||||
ProtonModalBottomSheetLayout(
|
||||
showBottomSheet = showBottomSheet,
|
||||
@@ -435,10 +443,12 @@ fun ConversationDetailScreen(
|
||||
viewModel.submit(ConversationDetailViewAction.DismissBottomSheet)
|
||||
actions.onComposeNewMessage(it.address)
|
||||
},
|
||||
onBlockClicked = { participant, messageId ->
|
||||
onBlockClicked = { participant, messageId, contactId ->
|
||||
viewModel.submit(
|
||||
ConversationDetailViewAction.BlockSender(
|
||||
messageId?.let { MessageIdUiModel(it.id) }, participant.address
|
||||
messageId = messageId?.let { MessageIdUiModel(it.id) },
|
||||
email = participant.address,
|
||||
contactId = contactId
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and Proton Mail.
|
||||
*
|
||||
* Proton Mail 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.
|
||||
*
|
||||
* Proton Mail 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 Proton Mail. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.protonmail.android.maildetail.presentation.ui.dialog
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import ch.protonmail.android.maildetail.presentation.R
|
||||
import ch.protonmail.android.design.compose.component.ProtonAlertDialog
|
||||
import ch.protonmail.android.design.compose.component.ProtonAlertDialogButton
|
||||
import ch.protonmail.android.design.compose.component.ProtonAlertDialogText
|
||||
import ch.protonmail.android.design.compose.theme.ProtonTheme
|
||||
import ch.protonmail.android.mailcontact.domain.model.ContactId
|
||||
import ch.protonmail.android.maildetail.presentation.model.BlockSenderDialogState
|
||||
import ch.protonmail.android.maildetail.presentation.model.MessageIdUiModel
|
||||
|
||||
@Composable
|
||||
fun BlockSenderDialog(
|
||||
state: BlockSenderDialogState,
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: (MessageIdUiModel?, String) -> Unit
|
||||
) {
|
||||
if (state is BlockSenderDialogState.Shown) {
|
||||
when (state) {
|
||||
is BlockSenderDialogState.Shown.ShowConfirmation -> BlockSenderDialog(
|
||||
email = state.email,
|
||||
contactId = state.contactId,
|
||||
onDismiss = onDismiss,
|
||||
onConfirm = { onConfirm(state.messageId, state.email) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BlockSenderDialog(
|
||||
email: String,
|
||||
contactId: ContactId?,
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: () -> Unit
|
||||
) {
|
||||
ProtonAlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {
|
||||
ProtonAlertDialogButton(
|
||||
titleResId = R.string.contact_actions_block_contact_dialog_button_block,
|
||||
textColor = ProtonTheme.colors.notificationError
|
||||
) { onConfirm() }
|
||||
},
|
||||
dismissButton = {
|
||||
ProtonAlertDialogButton(R.string.contact_actions_block_contact_dialog_button_cancel) { onDismiss() }
|
||||
},
|
||||
title = stringResource(
|
||||
id = contactId?.let { R.string.contact_actions_block_contact }
|
||||
?: R.string.contact_actions_block_address
|
||||
),
|
||||
text = {
|
||||
ProtonAlertDialogText(
|
||||
text = stringResource(
|
||||
id = R.string.contact_actions_block_contact_dialog_text,
|
||||
email
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
+14
-11
@@ -387,6 +387,8 @@ class ConversationDetailViewModel @Inject constructor(
|
||||
is ScrollRequestCompleted,
|
||||
is ConversationDetailViewAction.ReportPhishing,
|
||||
is ConversationDetailViewAction.ReportPhishingDismissed,
|
||||
is ConversationDetailViewAction.BlockSender,
|
||||
is ConversationDetailViewAction.BlockSenderDismissed,
|
||||
is ConversationDetailViewAction.MarkMessageAsLegitimate,
|
||||
is ConversationDetailViewAction.MarkMessageAsLegitimateDismissed,
|
||||
is ConversationDetailViewAction.EditScheduleSendMessageDismissed,
|
||||
@@ -429,7 +431,7 @@ class ConversationDetailViewModel @Inject constructor(
|
||||
handleMarkMessageAsLegitimateConfirmed(action)
|
||||
|
||||
is ConversationDetailViewAction.UnblockSender -> handleUnblockSender(action)
|
||||
is ConversationDetailViewAction.BlockSender -> handleBlockSender(action)
|
||||
is ConversationDetailViewAction.BlockSenderConfirmed -> handleBlockSenderConfirmed(action)
|
||||
is ConversationDetailViewAction.EditScheduleSendMessageConfirmed -> handleEditScheduleSendMessage(action)
|
||||
is ConversationDetailViewAction.PrintMessage -> handlePrintMessage(action.context, action.messageId)
|
||||
is ConversationDetailViewAction.RetryRsvpEventLoading ->
|
||||
@@ -1693,19 +1695,20 @@ class ConversationDetailViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleBlockSender(action: ConversationDetailViewAction.BlockSender) = viewModelScope.launch {
|
||||
private fun handleBlockSenderConfirmed(action: ConversationDetailViewAction.BlockSenderConfirmed) =
|
||||
viewModelScope.launch {
|
||||
blockSender(
|
||||
userId = primaryUserId.first(),
|
||||
email = action.email
|
||||
).fold(
|
||||
ifLeft = { Timber.e("Failed to block sender in message ${action.messageId?.id}") },
|
||||
ifRight = { action.messageId?.let { setOrRefreshMessageBody(it) } }
|
||||
)
|
||||
viewModelScope.launch {
|
||||
blockSender(
|
||||
userId = primaryUserId.first(),
|
||||
email = action.email
|
||||
).fold(
|
||||
ifLeft = { Timber.e("Failed to block sender in message ${action.messageId?.id}") },
|
||||
ifRight = { action.messageId?.let { setOrRefreshMessageBody(it) } }
|
||||
)
|
||||
|
||||
emitNewStateFrom(action)
|
||||
emitNewStateFrom(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleGetRsvpEvent(messageId: MessageId, refresh: Boolean) {
|
||||
viewModelScope.launch {
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and Proton Mail.
|
||||
*
|
||||
* Proton Mail 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.
|
||||
*
|
||||
* Proton Mail 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 Proton Mail. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.protonmail.android.maildetail.presentation.reducer
|
||||
|
||||
import ch.protonmail.android.maildetail.presentation.model.BlockSenderDialogState
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailOperation
|
||||
import ch.protonmail.android.maildetail.presentation.model.ConversationDetailViewAction
|
||||
import ch.protonmail.android.maildetail.presentation.model.MessageIdUiModel
|
||||
import ch.protonmail.android.testdata.contact.ContactIdSample
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class ConversationBlockSenderDialogReducerTest(
|
||||
private val testName: String,
|
||||
private val testInput: TestInput
|
||||
) {
|
||||
|
||||
private val blockSenderDialogReducer = ConversationBlockSenderDialogReducer()
|
||||
|
||||
@Test
|
||||
fun `should produce the expected new state`() = with(testInput) {
|
||||
val actualState = blockSenderDialogReducer.newStateFrom(operation)
|
||||
|
||||
assertEquals(testName, expectedState, actualState)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val transitions = listOf(
|
||||
TestInput(
|
||||
operation = ConversationDetailViewAction.BlockSenderDismissed,
|
||||
expectedState = BlockSenderDialogState.Hidden
|
||||
),
|
||||
TestInput(
|
||||
operation = ConversationDetailViewAction.BlockSenderConfirmed(
|
||||
MessageIdUiModel("msg-123"), "test@example.com"
|
||||
),
|
||||
expectedState = BlockSenderDialogState.Hidden
|
||||
),
|
||||
TestInput(
|
||||
operation = ConversationDetailViewAction.BlockSender(
|
||||
messageId = MessageIdUiModel("HtmlInvoice"),
|
||||
email = "test@example.com",
|
||||
contactId = ContactIdSample.Doe
|
||||
),
|
||||
expectedState = BlockSenderDialogState.Shown.ShowConfirmation(
|
||||
messageId = MessageIdUiModel("HtmlInvoice"),
|
||||
email = "test@example.com",
|
||||
contactId = ContactIdSample.Doe
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun data(): Collection<Array<Any>> {
|
||||
return transitions.map {
|
||||
val testName = """
|
||||
Operation: ${it.operation}
|
||||
Expected State: ${it.expectedState}
|
||||
""".trimIndent()
|
||||
arrayOf(testName, it)
|
||||
}
|
||||
}
|
||||
|
||||
data class TestInput(
|
||||
val operation: ConversationDetailOperation.AffectingBlockSenderDialog,
|
||||
val expectedState: BlockSenderDialogState
|
||||
)
|
||||
}
|
||||
}
|
||||
+18
@@ -78,6 +78,7 @@ class ConversationDetailReducerTest(
|
||||
private val bottomSheetReducer = mockk<BottomSheetReducer>(relaxed = true)
|
||||
private val deleteDialogReducer = mockk<ConversationDeleteDialogReducer>(relaxed = true)
|
||||
private val reportPhishingDialogReducer = mockk<ConversationReportPhishingDialogReducer>(relaxed = true)
|
||||
private val blockSenderDialogReducer = mockk<ConversationBlockSenderDialogReducer>(relaxed = true)
|
||||
private val trashedMessagesBannerReducer = mockk<HiddenMessagesBannerReducer>(relaxed = true)
|
||||
private val markAsLegitimateDialogReducer = mockk<MarkAsLegitimateDialogReducer>(relaxed = true)
|
||||
private val editScheduledMessageDialogReducer = mockk<EditScheduledMessageDialogReducer>(relaxed = true)
|
||||
@@ -88,6 +89,7 @@ class ConversationDetailReducerTest(
|
||||
bottomSheetReducer = bottomSheetReducer,
|
||||
deleteDialogReducer = deleteDialogReducer,
|
||||
reportPhishingDialogReducer = reportPhishingDialogReducer,
|
||||
blockSenderDialogReducer = blockSenderDialogReducer,
|
||||
hiddenMessagesBannerReducer = trashedMessagesBannerReducer,
|
||||
markAsLegitimateDialogReducer = markAsLegitimateDialogReducer,
|
||||
editScheduledMessageDialogReducer = editScheduledMessageDialogReducer,
|
||||
@@ -181,6 +183,12 @@ class ConversationDetailReducerTest(
|
||||
verify { reportPhishingDialogReducer wasNot Called }
|
||||
}
|
||||
|
||||
if (reducesBlockSenderDialog) {
|
||||
verify { blockSenderDialogReducer.newStateFrom(any()) }
|
||||
} else {
|
||||
verify { blockSenderDialogReducer wasNot Called }
|
||||
}
|
||||
|
||||
if (reducesMarkAsLegitimateDialog) {
|
||||
verify { markAsLegitimateDialogReducer.newStateFrom(any()) }
|
||||
} else {
|
||||
@@ -210,6 +218,7 @@ class ConversationDetailReducerTest(
|
||||
val reducesDeleteDialog: Boolean,
|
||||
val reducesTrashedMessagesBanner: Boolean,
|
||||
val reducesReportPhishingDialog: Boolean,
|
||||
val reducesBlockSenderDialog: Boolean,
|
||||
val reducesMarkAsLegitimateDialog: Boolean,
|
||||
val reducesEditScheduleSendDialog: Boolean
|
||||
) {
|
||||
@@ -278,6 +287,13 @@ class ConversationDetailReducerTest(
|
||||
MessageId(messageId.id)
|
||||
) affects listOf(ReportPhishingDialog),
|
||||
ConversationDetailViewAction.ReportPhishingDismissed affects listOf(ReportPhishingDialog),
|
||||
ConversationDetailViewAction.BlockSender(
|
||||
MessageIdUiModel(messageId.id), participant.participantAddress, null
|
||||
) affects listOf(BottomSheet, BlockSenderDialog),
|
||||
ConversationDetailViewAction.BlockSenderConfirmed(
|
||||
MessageIdUiModel(messageId.id), participant.participantAddress
|
||||
) affects listOf(BlockSenderDialog),
|
||||
ConversationDetailViewAction.BlockSenderDismissed affects listOf(BlockSenderDialog),
|
||||
ConversationDetailViewAction.MarkMessageAsLegitimate(
|
||||
MessageId(messageId.id), isPhishing = true
|
||||
) affects listOf(MarkAsLegitimateDialog),
|
||||
@@ -401,6 +417,7 @@ private infix fun ConversationDetailOperation.affects(entities: List<Entity>) =
|
||||
reducesDeleteDialog = entities.contains(DeleteDialog),
|
||||
reducesTrashedMessagesBanner = entities.contains(HiddenMessagesBanner),
|
||||
reducesReportPhishingDialog = entities.contains(ReportPhishingDialog),
|
||||
reducesBlockSenderDialog = entities.contains(BlockSenderDialog),
|
||||
reducesMarkAsLegitimateDialog = entities.contains(MarkAsLegitimateDialog),
|
||||
reducesEditScheduleSendDialog = entities.contains(EditScheduleSendDialog)
|
||||
)
|
||||
@@ -422,6 +439,7 @@ private data object MessageScroll : Entity
|
||||
private data object DeleteDialog : Entity
|
||||
private data object HiddenMessagesBanner : Entity
|
||||
private data object ReportPhishingDialog : Entity
|
||||
private data object BlockSenderDialog : Entity
|
||||
private data object MarkAsLegitimateDialog : Entity
|
||||
private data object EditScheduleSendDialog : Entity
|
||||
|
||||
|
||||
+2
@@ -126,6 +126,7 @@ import ch.protonmail.android.maildetail.presentation.model.MarkAsLegitimateDialo
|
||||
import ch.protonmail.android.maildetail.presentation.model.MessageIdUiModel
|
||||
import ch.protonmail.android.maildetail.presentation.model.MoreActionsBottomSheetEntryPoint
|
||||
import ch.protonmail.android.maildetail.presentation.model.ReportPhishingDialogState
|
||||
import ch.protonmail.android.maildetail.presentation.reducer.ConversationBlockSenderDialogReducer
|
||||
import ch.protonmail.android.maildetail.presentation.reducer.ConversationDeleteDialogReducer
|
||||
import ch.protonmail.android.maildetail.presentation.reducer.ConversationDetailMessagesReducer
|
||||
import ch.protonmail.android.maildetail.presentation.reducer.ConversationDetailMetadataReducer
|
||||
@@ -483,6 +484,7 @@ internal class ConversationDetailViewModelIntegrationTest {
|
||||
),
|
||||
deleteDialogReducer = ConversationDeleteDialogReducer(),
|
||||
reportPhishingDialogReducer = ConversationReportPhishingDialogReducer(),
|
||||
blockSenderDialogReducer = ConversationBlockSenderDialogReducer(),
|
||||
hiddenMessagesBannerReducer = HiddenMessagesBannerReducer(),
|
||||
markAsLegitimateDialogReducer = MarkAsLegitimateDialogReducer(),
|
||||
editScheduledMessageDialogReducer = EditScheduledMessageDialogReducer(),
|
||||
|
||||
+18
-1
@@ -2043,7 +2043,7 @@ class ConversationDetailViewModelTest {
|
||||
// When
|
||||
viewModel.state.test {
|
||||
initialStateEmitted()
|
||||
viewModel.submit(ConversationDetailViewAction.BlockSender(messageIdUiModel, email))
|
||||
viewModel.submit(ConversationDetailViewAction.BlockSenderConfirmed(messageIdUiModel, email))
|
||||
|
||||
advanceUntilIdle()
|
||||
|
||||
@@ -2053,6 +2053,23 @@ class ConversationDetailViewModelTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `do not call block sender when dismissed`() = runTest {
|
||||
// Given
|
||||
viewModel.state.test {
|
||||
initialStateEmitted()
|
||||
|
||||
// When
|
||||
viewModel.submit(ConversationDetailViewAction.BlockSenderDismissed)
|
||||
|
||||
advanceUntilIdle()
|
||||
|
||||
// Then
|
||||
coVerify(exactly = 0) { blockSender(userId, any()) }
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun setupCollapsedToExpandMessagesState(
|
||||
withUnreadMessage: Boolean = false
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ package ch.protonmail.android.mailmessage.presentation.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import ch.protonmail.android.mailcontact.domain.model.ContactId
|
||||
import ch.protonmail.android.mailmessage.domain.model.Participant
|
||||
import ch.protonmail.android.mailmessage.presentation.R
|
||||
|
||||
@@ -53,7 +54,7 @@ sealed class ContactActionUiModel(
|
||||
descriptionRes = R.string.contact_actions_add_contact_description
|
||||
)
|
||||
|
||||
data class BlockContact(val participant: Participant) : ContactActionUiModel(
|
||||
data class BlockContact(val participant: Participant, val contactId: ContactId) : ContactActionUiModel(
|
||||
iconRes = R.drawable.ic_proton_circle_slash,
|
||||
textRes = R.string.contact_actions_block_contact,
|
||||
descriptionRes = R.string.contact_actions_block_contact_description
|
||||
|
||||
+12
-5
@@ -54,11 +54,18 @@ class ContactActionsBottomSheetReducer @Inject constructor() {
|
||||
emptyList()
|
||||
} else {
|
||||
buildList {
|
||||
val action = when {
|
||||
contactId == null && isSenderBlocked -> ContactActionUiModel.UnblockAddress(participant)
|
||||
contactId == null && !isSenderBlocked -> ContactActionUiModel.BlockAddress(participant)
|
||||
contactId != null && isSenderBlocked -> ContactActionUiModel.UnblockContact(participant)
|
||||
else -> ContactActionUiModel.BlockContact(participant)
|
||||
val action = if (contactId == null) {
|
||||
if (isSenderBlocked) {
|
||||
ContactActionUiModel.UnblockAddress(participant)
|
||||
} else {
|
||||
ContactActionUiModel.BlockAddress(participant)
|
||||
}
|
||||
} else {
|
||||
if (isSenderBlocked) {
|
||||
ContactActionUiModel.UnblockContact(participant)
|
||||
} else {
|
||||
ContactActionUiModel.BlockContact(participant, contactId)
|
||||
}
|
||||
}
|
||||
add(action)
|
||||
}
|
||||
|
||||
+9
-4
@@ -42,6 +42,7 @@ import ch.protonmail.android.design.compose.theme.titleLargeNorm
|
||||
import ch.protonmail.android.mailcommon.presentation.compose.Avatar
|
||||
import ch.protonmail.android.mailcommon.presentation.compose.MailDimens
|
||||
import ch.protonmail.android.mailcommon.presentation.model.AvatarUiModel
|
||||
import ch.protonmail.android.mailcontact.domain.model.ContactId
|
||||
import ch.protonmail.android.mailmessage.domain.model.MessageId
|
||||
import ch.protonmail.android.mailmessage.domain.model.Participant
|
||||
import ch.protonmail.android.mailmessage.presentation.model.ContactActionUiModel
|
||||
@@ -133,9 +134,13 @@ private fun callbackForActions(
|
||||
is ContactActionUiModel.CopyAddress -> actions.onCopyAddressClicked(action.address)
|
||||
is ContactActionUiModel.CopyName -> actions.onCopyNameClicked(action.name)
|
||||
is ContactActionUiModel.NewMessage -> actions.onNewMessageClicked(action.participant)
|
||||
is ContactActionUiModel.BlockContact -> actions.onBlockClicked(action.participant, sheetOrigin.getMessageId())
|
||||
is ContactActionUiModel.BlockContact -> actions.onBlockClicked(
|
||||
action.participant,
|
||||
sheetOrigin.getMessageId(), action.contactId
|
||||
)
|
||||
|
||||
is ContactActionUiModel.UnblockContact -> actions.onUnblockClicked(action.participant, sheetOrigin.getMessageId())
|
||||
is ContactActionUiModel.BlockAddress -> actions.onBlockClicked(action.participant, sheetOrigin.getMessageId())
|
||||
is ContactActionUiModel.BlockAddress -> actions.onBlockClicked(action.participant, sheetOrigin.getMessageId(), null)
|
||||
is ContactActionUiModel.UnblockAddress -> actions.onUnblockClicked(action.participant, sheetOrigin.getMessageId())
|
||||
}
|
||||
|
||||
@@ -194,7 +199,7 @@ object ContactActionsBottomSheetContent {
|
||||
val onCopyNameClicked: (name: String) -> Unit,
|
||||
val onNewMessageClicked: (participant: Participant) -> Unit,
|
||||
val onAddContactClicked: (participant: Participant) -> Unit,
|
||||
val onBlockClicked: (participant: Participant, messageId: MessageId?) -> Unit,
|
||||
val onBlockClicked: (participant: Participant, messageId: MessageId?, contactId: ContactId?) -> Unit,
|
||||
val onUnblockClicked: (participant: Participant, messageId: MessageId?) -> Unit
|
||||
)
|
||||
}
|
||||
@@ -228,7 +233,7 @@ fun ContactActionsBottomSheetContentPreview() {
|
||||
onCopyNameClicked = {},
|
||||
onNewMessageClicked = {},
|
||||
onAddContactClicked = {},
|
||||
onBlockClicked = { _, _ -> },
|
||||
onBlockClicked = { _, _, _ -> },
|
||||
onUnblockClicked = { _, _ -> }
|
||||
)
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
~ along with Proton Mail. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<plurals name="selected_count_title">
|
||||
<item quantity="one">%d Selected</item>
|
||||
<item quantity="other">%d Selected</item>
|
||||
@@ -73,6 +73,9 @@
|
||||
<string name="contact_actions_add_contact_description">Save this recipient as a contact</string>
|
||||
<string name="contact_actions_block_contact">Block this contact</string>
|
||||
<string name="contact_actions_block_contact_description">Block this contact</string>
|
||||
<string name="contact_actions_block_contact_dialog_text">Emails from <xliff:g id="email">%1$s</xliff:g> will no longer be delivered and will be permanently deleted. You can manage blocked email addresses in the settings.</string>
|
||||
<string name="contact_actions_block_contact_dialog_button_block">Block</string>
|
||||
<string name="contact_actions_block_contact_dialog_button_cancel">Cancel</string>
|
||||
<string name="contact_actions_unblock_contact">Block this contact</string>
|
||||
<string name="contact_actions_unblock_contact_description">Block this contact</string>
|
||||
<string name="contact_actions_block_address">Block this address</string>
|
||||
|
||||
+71
-7
@@ -20,11 +20,13 @@ package ch.protonmail.android.mailmessage.presentation.reducer
|
||||
|
||||
import ch.protonmail.android.mailcommon.presentation.model.BottomSheetState
|
||||
import ch.protonmail.android.mailcommon.presentation.sample.ParticipantAvatarSample
|
||||
import ch.protonmail.android.mailcontact.domain.model.ContactId
|
||||
import ch.protonmail.android.mailmessage.domain.model.MessageId
|
||||
import ch.protonmail.android.mailmessage.domain.model.Participant
|
||||
import ch.protonmail.android.mailmessage.presentation.model.ContactActionUiModel
|
||||
import ch.protonmail.android.mailmessage.presentation.model.bottomsheet.ContactActionsBottomSheetState
|
||||
import ch.protonmail.android.testdata.contact.ContactActionsGroupsSample
|
||||
import ch.protonmail.android.testdata.contact.ContactSample
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
@@ -61,6 +63,7 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
private val sampleOrigin =
|
||||
ContactActionsBottomSheetState.Origin.MessageDetails(MessageId("msg-1"))
|
||||
|
||||
|
||||
private val transitionsFromLoadingState = listOf(
|
||||
TestInput(
|
||||
currentState = BottomSheetState(ContactActionsBottomSheetState.Loading),
|
||||
@@ -76,7 +79,12 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
contentState = ContactActionsBottomSheetState.Data(
|
||||
participant = sampleParticipant,
|
||||
avatarUiModel = sampleAvatar,
|
||||
actions = ContactActionsGroupsSample.defaultForContact(sampleParticipant, false),
|
||||
actions = expectedGroupsFor(
|
||||
participant = sampleParticipant,
|
||||
contactId = sampleContact.id,
|
||||
isSenderBlocked = false,
|
||||
isPrimaryUserAddress = false
|
||||
),
|
||||
origin = sampleOrigin
|
||||
)
|
||||
)
|
||||
@@ -95,7 +103,12 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
contentState = ContactActionsBottomSheetState.Data(
|
||||
participant = sampleParticipant,
|
||||
avatarUiModel = sampleAvatar,
|
||||
actions = ContactActionsGroupsSample.defaultForContact(sampleParticipant, true),
|
||||
actions = expectedGroupsFor(
|
||||
participant = sampleParticipant,
|
||||
contactId = sampleContact.id,
|
||||
isSenderBlocked = true,
|
||||
isPrimaryUserAddress = false
|
||||
),
|
||||
origin = sampleOrigin
|
||||
)
|
||||
)
|
||||
@@ -114,7 +127,12 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
contentState = ContactActionsBottomSheetState.Data(
|
||||
participant = sampleParticipant,
|
||||
avatarUiModel = sampleAvatar,
|
||||
actions = ContactActionsGroupsSample.defaultForNoContact(sampleParticipant, true),
|
||||
actions = expectedGroupsFor(
|
||||
participant = sampleParticipant,
|
||||
contactId = null,
|
||||
isSenderBlocked = true,
|
||||
isPrimaryUserAddress = false
|
||||
),
|
||||
origin = sampleOrigin
|
||||
)
|
||||
)
|
||||
@@ -133,7 +151,12 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
contentState = ContactActionsBottomSheetState.Data(
|
||||
participant = sampleParticipant,
|
||||
avatarUiModel = sampleAvatar,
|
||||
actions = ContactActionsGroupsSample.defaultForNoContact(sampleParticipant, false),
|
||||
actions = expectedGroupsFor(
|
||||
participant = sampleParticipant,
|
||||
contactId = null,
|
||||
isSenderBlocked = false,
|
||||
isPrimaryUserAddress = false
|
||||
),
|
||||
origin = sampleOrigin
|
||||
)
|
||||
)
|
||||
@@ -152,8 +175,11 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
contentState = ContactActionsBottomSheetState.Data(
|
||||
participant = primaryUserParticipant,
|
||||
avatarUiModel = sampleAvatar,
|
||||
actions = ContactActionsGroupsSample.defaultForNoContact(
|
||||
primaryUserParticipant, isAddressBlocked = false, isPrimaryUserAddress = true
|
||||
actions = expectedGroupsFor(
|
||||
participant = primaryUserParticipant,
|
||||
contactId = null,
|
||||
isSenderBlocked = false,
|
||||
isPrimaryUserAddress = true
|
||||
),
|
||||
origin = sampleOrigin
|
||||
)
|
||||
@@ -161,6 +187,44 @@ internal class ContactActionsBottomSheetReducerTest(
|
||||
)
|
||||
)
|
||||
|
||||
private fun expectedGroupsFor(
|
||||
participant: Participant,
|
||||
contactId: ContactId?,
|
||||
isSenderBlocked: Boolean,
|
||||
isPrimaryUserAddress: Boolean
|
||||
): ContactActionsBottomSheetState.ContactActionsGroups {
|
||||
val first = listOf(
|
||||
ContactActionUiModel.NewMessage(participant)
|
||||
).toImmutableList()
|
||||
|
||||
val second = listOf(
|
||||
ContactActionUiModel.CopyAddress(participant.address),
|
||||
ContactActionUiModel.CopyName(participant.name)
|
||||
).toImmutableList()
|
||||
|
||||
val third = if (isPrimaryUserAddress) {
|
||||
emptyList()
|
||||
} else {
|
||||
listOf(
|
||||
when {
|
||||
contactId == null && !isSenderBlocked -> ContactActionUiModel.BlockAddress(participant)
|
||||
contactId == null && isSenderBlocked -> ContactActionUiModel.UnblockAddress(participant)
|
||||
contactId != null && !isSenderBlocked -> ContactActionUiModel.BlockContact(
|
||||
participant, contactId
|
||||
)
|
||||
|
||||
else -> ContactActionUiModel.UnblockContact(participant)
|
||||
}
|
||||
)
|
||||
}.toImmutableList()
|
||||
|
||||
return ContactActionsBottomSheetState.ContactActionsGroups(
|
||||
firstGroup = first,
|
||||
secondGroup = second,
|
||||
thirdGroup = third
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun data() = transitionsFromLoadingState
|
||||
|
||||
Vendored
+1
-1
@@ -45,7 +45,7 @@ object ContactActionsGroupsSample {
|
||||
if (isContactBlocked) {
|
||||
add(ContactActionUiModel.UnblockContact(participant))
|
||||
} else {
|
||||
add(ContactActionUiModel.BlockContact(participant))
|
||||
add(ContactActionUiModel.BlockContact(participant, ContactIdSample.Doe))
|
||||
}
|
||||
}.toImmutableList()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user