Merge branch 'release/7.9.6'

This commit is contained in:
Niccolò Forlini
2026-04-30 09:28:38 +02:00
7 changed files with 67 additions and 6 deletions
@@ -773,10 +773,10 @@ fun Home(
onShowErrorSnackbar = {
showErrorSnackbar(it)
},
onSendGroupMessage = {
onSendGroupMessage = { groupName, members ->
navController.navigate(
Screen.MessageActionComposer(
DraftAction.ComposeToAddresses(it)
DraftAction.ComposeToContactGroup(groupName, members)
)
)
},
@@ -426,7 +426,7 @@ internal fun NavGraphBuilder.addContactSearch(navController: NavHostController)
internal fun NavGraphBuilder.addContactGroupDetails(
navController: NavHostController,
onShowErrorSnackbar: (String) -> Unit,
onSendGroupMessage: (List<String>) -> Unit,
onSendGroupMessage: (groupName: String, members: List<String>) -> Unit,
onOpenContact: (ContactId) -> Unit,
showFeatureMissingSnackbar: () -> Unit
) {
@@ -108,6 +108,7 @@ fun DraftAction.toDraftCreateMode(): DraftCreateMode? = when (this) {
DraftAction.Compose -> DraftCreateMode.Empty
is DraftAction.MailTo -> DraftCreateMode.Mailto(this.uri)
is DraftAction.ComposeToAddresses,
is DraftAction.ComposeToContactGroup,
is DraftAction.PrefillForShare -> {
Timber.e("rust-draft: mapping draft action $this failed! Unsupported by rust DraftCreateMode type")
null
@@ -113,6 +113,7 @@ import ch.protonmail.android.mailevents.domain.model.AppEvent
import ch.protonmail.android.mailmessage.domain.model.DraftAction
import ch.protonmail.android.mailmessage.domain.model.DraftAction.Compose
import ch.protonmail.android.mailmessage.domain.model.DraftAction.ComposeToAddresses
import ch.protonmail.android.mailmessage.domain.model.DraftAction.ComposeToContactGroup
import ch.protonmail.android.mailmessage.domain.model.DraftAction.Forward
import ch.protonmail.android.mailmessage.domain.model.DraftAction.MailTo
import ch.protonmail.android.mailmessage.domain.model.DraftAction.PrefillForShare
@@ -508,6 +509,12 @@ class ComposerViewModel @AssistedInject constructor(
}
}
is ComposeToContactGroup -> {
prefillForNewDraft().onRight {
prefillForComposeToAction(listOf(draftAction.toGroupRecipient()))
}
}
is Forward,
is Reply,
is ReplyAll,
@@ -989,6 +996,9 @@ class ComposerViewModel @AssistedInject constructor(
}
}
private fun ComposeToContactGroup.toGroupRecipient(): RecipientUiModel.Group =
RecipientUiModel.Group(name = name, members = members, color = "")
private fun String.stripNewLines() = this.replace("[\n\r]".toRegex(), " ")
private fun logViewModelAction(action: ComposerAction, message: String) {
@@ -1178,6 +1178,48 @@ internal class ComposerViewModelTest {
}
}
@Test
fun `should set group recipient to state when contact group was given as an input`() = runTest {
// Given
val expectedUserId = expectedUserId { UserIdSample.Primary }
val groupName = "Friends"
val groupMembers = listOf("alice@example.com", "bob@example.com")
val expectedAction = DraftAction.ComposeToContactGroup(groupName, groupMembers)
val expectedDraftGroupRecipient = DraftRecipient.GroupRecipient(
name = groupName,
recipients = groupMembers.map { address ->
DraftRecipient.SingleRecipient(
name = "",
address = address,
validity = DraftRecipientValidity.Validating,
privacyLock = PrivacyLock.None
)
}
)
expectNoInputDraftMessageId()
expectInputDraftAction { expectedAction }
expectStoreDraftSubjectSucceeds(Subject(""))
expectStoreDraftBodySucceeds(DraftBody(""))
expectUpdateRecipientsSucceeds(listOf(expectedDraftGroupRecipient), emptyList(), emptyList())
expectObservedMessageAttachments()
expectNoRestoredState(savedStateHandle)
expectInitComposerWithNewEmptyDraftSucceeds(expectedUserId) {
DraftFieldsTestData.EmptyDraftWithPrimarySender
}
// When
val viewModel = viewModel()
viewModel.composerStates.test {
// Then
assertEquals(
RecipientUiModel.Group(name = groupName, members = groupMembers, color = ""),
recipientsStateManager.recipients.value.toRecipients.firstOrNull()
)
cancelAndIgnoreRemainingEvents()
}
}
@Test
fun `should show warning when send button is clicked with expiration set and external recipients`() = runTest {
// Given
@@ -143,7 +143,12 @@ private fun ContactGroupDetails(
SendGroupMessageAction(
memberCount = uiModel.memberCount,
onClick = { actions.onSendGroupMessage(uiModel.members.map { it.emailAddress }) }
onClick = {
actions.onSendGroupMessage(
uiModel.name,
uiModel.members.map { it.emailAddress }
)
}
)
Column(
@@ -274,7 +279,7 @@ fun ContactGroupDetailsScreenPreview() {
actions = ContactGroupDetailsScreen.Actions(
onBack = {},
onShowErrorSnackbar = {},
onSendGroupMessage = {},
onSendGroupMessage = { _, _ -> },
onOpenContact = {},
showFeatureMissingSnackbar = {}
)
@@ -287,7 +292,7 @@ object ContactGroupDetailsScreen {
data class Actions(
val onBack: () -> Unit,
val onShowErrorSnackbar: (String) -> Unit,
val onSendGroupMessage: (List<String>) -> Unit,
val onSendGroupMessage: (groupName: String, members: List<String>) -> Unit,
val onOpenContact: (ContactId) -> Unit,
val showFeatureMissingSnackbar: () -> Unit
)
@@ -39,6 +39,9 @@ sealed interface DraftAction {
@Serializable
data class ComposeToAddresses(val recipients: List<String>) : DraftAction
@Serializable
data class ComposeToContactGroup(val name: String, val members: List<String>) : DraftAction
@Serializable
data class PrefillForShare(val intentShareInfo: IntentShareInfo) : DraftAction