From 5da0c09d63ee1fdd9ca4aba973d0cf95de4ea388 Mon Sep 17 00:00:00 2001 From: Marino Meneghel Date: Thu, 14 Aug 2025 15:01:43 +0200 Subject: [PATCH] Add draft mime type to domain and ui models and on state when draft ready ET-4304 --- .../composer/data/mapper/DraftMapper.kt | 20 +++++++++++++++++-- .../mailcomposer/domain/model/DraftFields.kt | 1 + .../domain/model/DraftFieldsTest.kt | 1 + .../presentation/model/ComposerStates.kt | 3 +++ .../modifications/MainStateModification.kt | 3 ++- .../viewmodel/ComposerViewModel.kt | 6 ++++++ .../mapper/effects/CompositeEventTest.kt | 2 ++ .../EffectsStateModificationTest.kt | 2 ++ .../MainStateModificationTest.kt | 3 ++- .../viewmodel/ComposerViewModelTest.kt | 11 ++++++++++ .../testdata/composer/DraftFieldsTestData.kt | 3 +++ 11 files changed, 51 insertions(+), 4 deletions(-) diff --git a/mail-composer/data/src/main/kotlin/ch/protonmail/android/composer/data/mapper/DraftMapper.kt b/mail-composer/data/src/main/kotlin/ch/protonmail/android/composer/data/mapper/DraftMapper.kt index 1e418e1550..dba6485690 100644 --- a/mail-composer/data/src/main/kotlin/ch/protonmail/android/composer/data/mapper/DraftMapper.kt +++ b/mail-composer/data/src/main/kotlin/ch/protonmail/android/composer/data/mapper/DraftMapper.kt @@ -16,6 +16,8 @@ * along with Proton Mail. If not, see . */ +@file:Suppress("TooManyFunctions") + package ch.protonmail.android.composer.data.mapper import ch.protonmail.android.composer.data.local.LocalDraft @@ -26,6 +28,7 @@ import ch.protonmail.android.composer.data.wrapper.DraftWrapperWithSyncStatus import ch.protonmail.android.mailcommon.data.mapper.LocalAttachmentData import ch.protonmail.android.mailcommon.data.mapper.LocalComposerRecipient import ch.protonmail.android.mailcommon.data.mapper.LocalDraftSendResult +import ch.protonmail.android.mailcommon.data.mapper.LocalMimeType import ch.protonmail.android.mailcommon.data.mapper.toDataError import ch.protonmail.android.mailcommon.domain.annotation.MissingRustApi import ch.protonmail.android.mailcommon.domain.model.DataError @@ -33,10 +36,11 @@ import ch.protonmail.android.mailcomposer.domain.model.ChangeSenderError import ch.protonmail.android.mailcomposer.domain.model.DraftBody import ch.protonmail.android.mailcomposer.domain.model.DraftFields import ch.protonmail.android.mailcomposer.domain.model.DraftFieldsWithSyncStatus -import ch.protonmail.android.mailcomposer.domain.model.MessagePassword -import ch.protonmail.android.mailcomposer.domain.model.MessagePasswordError +import ch.protonmail.android.mailcomposer.domain.model.DraftMimeType import ch.protonmail.android.mailcomposer.domain.model.MessageExpirationError import ch.protonmail.android.mailcomposer.domain.model.MessageExpirationTime +import ch.protonmail.android.mailcomposer.domain.model.MessagePassword +import ch.protonmail.android.mailcomposer.domain.model.MessagePasswordError import ch.protonmail.android.mailcomposer.domain.model.MessageSendingStatus import ch.protonmail.android.mailcomposer.domain.model.OpenDraftError import ch.protonmail.android.mailcomposer.domain.model.RecipientsBcc @@ -79,6 +83,7 @@ import uniffi.proton_mail_uniffi.DraftSenderAddressChangeError import uniffi.proton_mail_uniffi.DraftSenderAddressChangeErrorReason import uniffi.proton_mail_uniffi.DraftSenderAddressList import uniffi.proton_mail_uniffi.DraftSyncStatus +import uniffi.proton_mail_uniffi.MimeType import uniffi.proton_mail_uniffi.SingleRecipientEntry import kotlin.time.DurationUnit import kotlin.time.Instant @@ -106,6 +111,7 @@ fun LocalDraft.toDraftFields() = DraftFields( sender = SenderEmail(this.sender), subject = Subject(this.subject), body = DraftBody(this.body), + mimeType = this.mimeType.toDraftMimeType(), recipientsTo = RecipientsTo(this.recipientsTo.toRecipients()), recipientsCc = RecipientsCc(this.recipientsCc.toRecipients()), recipientsBcc = RecipientsBcc(this.recipientsBcc.toRecipients()) @@ -394,6 +400,16 @@ private fun DraftAttachmentUploadError.toDataError() = when (this) { } } +private fun LocalMimeType.toDraftMimeType() = when (this) { + MimeType.APPLICATION_JSON, + MimeType.APPLICATION_PDF, + MimeType.MESSAGE_RFC822, + MimeType.MULTIPART_MIXED, + MimeType.MULTIPART_RELATED, + MimeType.TEXT_HTML -> DraftMimeType.Html + MimeType.TEXT_PLAIN -> DraftMimeType.PlainText +} + @MissingRustApi // Hardcoded values in the mapping diff --git a/mail-composer/domain/src/main/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFields.kt b/mail-composer/domain/src/main/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFields.kt index 071e27f1b4..485b2390c9 100644 --- a/mail-composer/domain/src/main/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFields.kt +++ b/mail-composer/domain/src/main/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFields.kt @@ -22,6 +22,7 @@ data class DraftFields( val sender: SenderEmail, val subject: Subject, val body: DraftBody, + val mimeType: DraftMimeType, val recipientsTo: RecipientsTo, val recipientsCc: RecipientsCc, val recipientsBcc: RecipientsBcc diff --git a/mail-composer/domain/src/test/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFieldsTest.kt b/mail-composer/domain/src/test/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFieldsTest.kt index abff6f62ec..a3eedbeb62 100644 --- a/mail-composer/domain/src/test/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFieldsTest.kt +++ b/mail-composer/domain/src/test/kotlin/ch/protonmail/android/mailcomposer/domain/model/DraftFieldsTest.kt @@ -29,6 +29,7 @@ class DraftFieldsTest { sender = SenderEmail("A sender email"), subject = Subject("A test subject"), body = DraftBody("A draft body"), + mimeType = DraftMimeType.Html, recipientsTo = RecipientsTo(emptyList()), recipientsCc = RecipientsCc(emptyList()), recipientsBcc = RecipientsBcc(emptyList()) diff --git a/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/model/ComposerStates.kt b/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/model/ComposerStates.kt index 32b92ddb60..89770c3748 100644 --- a/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/model/ComposerStates.kt +++ b/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/model/ComposerStates.kt @@ -21,6 +21,7 @@ package ch.protonmail.android.mailcomposer.presentation.model import ch.protonmail.android.mailattachments.domain.model.AttachmentId import ch.protonmail.android.mailcommon.presentation.Effect import ch.protonmail.android.mailcommon.presentation.model.TextUiModel +import ch.protonmail.android.mailcomposer.domain.model.DraftMimeType import ch.protonmail.android.mailmessage.domain.model.MessageId import ch.protonmail.android.mailmessage.domain.model.Participant import ch.protonmail.android.mailmessage.presentation.model.attachment.AttachmentGroupUiModel @@ -45,6 +46,7 @@ sealed interface ComposerState { data class Main( val sender: SenderUiModel, + val draftType: DraftMimeType, val senderAddresses: ImmutableList, val isSubmittable: Boolean, val loadingType: LoadingType @@ -54,6 +56,7 @@ sealed interface ComposerState { fun initial() = Main( sender = SenderUiModel(""), + draftType = DraftMimeType.Html, senderAddresses = emptyList().toImmutableList(), isSubmittable = false, loadingType = LoadingType.None diff --git a/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/reducer/modifications/MainStateModification.kt b/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/reducer/modifications/MainStateModification.kt index f59a925498..250fc5eb46 100644 --- a/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/reducer/modifications/MainStateModification.kt +++ b/mail-composer/presentation/src/main/kotlin/ch/protonmail/android/mailcomposer/presentation/reducer/modifications/MainStateModification.kt @@ -29,7 +29,8 @@ internal sealed interface MainStateModification : ComposerStateModificationwith sender-email@ signature") private val draftDisplayBody = DraftDisplayBodyUiModel("draft display body") private val draftFields = DraftFields( SenderEmail("author@proton.me"), Subject("Here is the matter"), DraftBody("Decrypted body of this draft"), + DraftMimeType.Html, RecipientsTo(listOf(Recipient("you@proton.ch", "Name"))), RecipientsCc(emptyList()), RecipientsBcc(emptyList()) diff --git a/mail-composer/presentation/src/test/kotlin/ch/protonmail/android/mailcomposer/presentation/viewmodel/ComposerViewModelTest.kt b/mail-composer/presentation/src/test/kotlin/ch/protonmail/android/mailcomposer/presentation/viewmodel/ComposerViewModelTest.kt index 92c99034f5..ca57cdbbb1 100644 --- a/mail-composer/presentation/src/test/kotlin/ch/protonmail/android/mailcomposer/presentation/viewmodel/ComposerViewModelTest.kt +++ b/mail-composer/presentation/src/test/kotlin/ch/protonmail/android/mailcomposer/presentation/viewmodel/ComposerViewModelTest.kt @@ -37,6 +37,7 @@ import ch.protonmail.android.mailcommon.presentation.model.TextUiModel import ch.protonmail.android.mailcomposer.domain.model.DraftBody import ch.protonmail.android.mailcomposer.domain.model.DraftFields import ch.protonmail.android.mailcomposer.domain.model.DraftFieldsWithSyncStatus +import ch.protonmail.android.mailcomposer.domain.model.DraftMimeType import ch.protonmail.android.mailcomposer.domain.model.OpenDraftError import ch.protonmail.android.mailcomposer.domain.model.RecipientsBcc import ch.protonmail.android.mailcomposer.domain.model.RecipientsCc @@ -246,6 +247,7 @@ internal class ComposerViewModelTest { expectedSenderEmail, expectedSubject, expectedDraftBody, + DraftMimeType.Html, recipientsTo, recipientsCc, recipientsBcc @@ -372,6 +374,7 @@ internal class ComposerViewModelTest { sender = expectedSenderEmail, subject = expectedSubject, body = expectedDraftBody, + mimeType = DraftMimeType.Html, recipientsTo = recipientsTo, recipientsCc = recipientsCc, recipientsBcc = recipientsBcc @@ -412,6 +415,7 @@ internal class ComposerViewModelTest { sender = expectedSenderEmail, subject = expectedSubject, body = expectedDraftBody, + mimeType = DraftMimeType.Html, recipientsTo = recipientsTo, recipientsCc = recipientsCc, recipientsBcc = recipientsBcc @@ -456,6 +460,7 @@ internal class ComposerViewModelTest { sender = expectedSenderEmail, subject = expectedSubject, body = expectedDraftBody, + mimeType = DraftMimeType.Html, recipientsTo = recipientsTo, recipientsCc = recipientsCc, recipientsBcc = recipientsBcc @@ -863,6 +868,7 @@ internal class ComposerViewModelTest { expectedSenderEmail, expectedSubject, expectedDraftBody, + DraftMimeType.Html, recipientsTo, recipientsCc, recipientsBcc @@ -908,6 +914,7 @@ internal class ComposerViewModelTest { expectedSenderEmail, expectedSubject, expectedDraftBody, + DraftMimeType.Html, recipientsTo, recipientsCc, recipientsBcc @@ -990,6 +997,7 @@ internal class ComposerViewModelTest { sender = expectedSenderEmail, subject = expectedSubject, body = expectedDraftBody, + DraftMimeType.Html, recipientsTo = recipientsTo, recipientsCc = recipientsCc, recipientsBcc = recipientsBcc @@ -1101,6 +1109,7 @@ internal class ComposerViewModelTest { sender = expectedSenderEmail, subject = expectedSubject, body = expectedDraftBody, + mimeType = DraftMimeType.Html, recipientsTo = recipientsTo, recipientsCc = recipientsCc, recipientsBcc = recipientsBcc @@ -1141,6 +1150,7 @@ internal class ComposerViewModelTest { sender = expectedSenderEmail, subject = expectedSubject, body = expectedDraftBody, + mimeType = DraftMimeType.Html, recipientsTo = recipientsTo, recipientsCc = recipientsCc, recipientsBcc = recipientsBcc @@ -1445,6 +1455,7 @@ internal class ComposerViewModelTest { SenderEmail("author@proton.me"), Subject("Here is the matter"), DraftBody("Decrypted body of this draft"), + DraftMimeType.Html, RecipientsTo(listOf(Recipient("valid@email.com", "Valid Email"))), RecipientsCc(emptyList()), RecipientsBcc(emptyList()) diff --git a/test/test-data/src/main/kotlin/ch/protonmail/android/testdata/composer/DraftFieldsTestData.kt b/test/test-data/src/main/kotlin/ch/protonmail/android/testdata/composer/DraftFieldsTestData.kt index aa6d90c1dc..e8ed56811a 100644 --- a/test/test-data/src/main/kotlin/ch/protonmail/android/testdata/composer/DraftFieldsTestData.kt +++ b/test/test-data/src/main/kotlin/ch/protonmail/android/testdata/composer/DraftFieldsTestData.kt @@ -21,6 +21,7 @@ package ch.protonmail.android.testdata.composer import ch.protonmail.android.mailcommon.domain.sample.UserAddressSample import ch.protonmail.android.mailcomposer.domain.model.DraftBody import ch.protonmail.android.mailcomposer.domain.model.DraftFields +import ch.protonmail.android.mailcomposer.domain.model.DraftMimeType import ch.protonmail.android.mailcomposer.domain.model.RecipientsBcc import ch.protonmail.android.mailcomposer.domain.model.RecipientsCc import ch.protonmail.android.mailcomposer.domain.model.RecipientsTo @@ -45,6 +46,7 @@ object DraftFieldsTestData { expectedSubject: String = "Subject for the message", expectedSenderEmail: String = UserAddressSample.PrimaryAddress.email, expectedDraftBody: String = "I am plaintext", + expectedMimeType: DraftMimeType = DraftMimeType.Html, recipientsToAddresses: List = listOf(RecipientSample.NamelessRecipient.address), recipientsCcAddresses: List = listOf(RecipientSample.NamelessRecipient.address), recipientsBccAddresses: List = listOf(RecipientSample.NamelessRecipient.address) @@ -52,6 +54,7 @@ object DraftFieldsTestData { SenderEmail(expectedSenderEmail), Subject(expectedSubject), DraftBody(expectedDraftBody), + expectedMimeType, RecipientsTo(recipientsToAddresses.toRecipient()), RecipientsCc(recipientsCcAddresses.toRecipient()), RecipientsBcc(recipientsBccAddresses.toRecipient())