From 1de06016988c6d7a410c782dc4fb7ed4765d8085 Mon Sep 17 00:00:00 2001 From: Kevin Boulongne Date: Mon, 3 Mar 2025 15:34:52 +0100 Subject: [PATCH 1/3] feat: Handle signatures containing `+xxx` in the answering email --- .../data/cache/mailboxContent/MessageController.kt | 13 +++++++++++-- .../data/models/correspondent/Correspondent.kt | 14 +++++++++++++- .../java/com/infomaniak/mail/ui/MainViewModel.kt | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt index cbdfec54da..e50b56fcbe 100644 --- a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt +++ b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt @@ -59,10 +59,19 @@ class MessageController @Inject constructor(private val mailboxContentRealm: Rea fun getLastMessageToExecuteAction(thread: Thread): Message = with(thread) { val isNotScheduledDraft = "${Message::isScheduledDraft.name} == false" - val isNotFromMe = "SUBQUERY(${Message::from.name}, \$recipient, " + + + val isNotFromRealMe = "SUBQUERY(${Message::from.name}, \$recipient, " + "\$recipient.${Recipient::email.name} != '${AccountUtils.currentMailboxEmail}').@count > 0" - return messages.query("$isNotDraft AND $isNotScheduledDraft AND $isNotFromMe").find().lastOrNull() + val splittedEmail = AccountUtils.currentMailboxEmail?.split("@") + val start = splittedEmail?.first() + "+" + val end = "@" + splittedEmail?.last() + val isNotFromPlusMe = "SUBQUERY(${Message::from.name}, \$recipient," + + " \$recipient.${Recipient::email.name} BEGINSWITH '${start}'" + + " AND \$recipient.${Recipient::email.name} ENDSWITH '${end}'" + + ").@count > 0" + + return messages.query("$isNotDraft AND $isNotScheduledDraft AND ($isNotFromRealMe OR $isNotFromPlusMe)").find().lastOrNull() ?: messages.query("$isNotDraft AND $isNotScheduledDraft").find().lastOrNull() ?: messages.query(isNotScheduledDraft).find().lastOrNull() ?: messages.last() diff --git a/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt b/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt index c77a270dc6..d485a30302 100644 --- a/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt +++ b/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt @@ -30,7 +30,19 @@ interface Correspondent : Parcelable { val initials: String - fun isMe(): Boolean = AccountUtils.currentMailboxEmail?.lowercase() == email.lowercase() + fun isMe(): Boolean { + val userEmail = AccountUtils.currentMailboxEmail?.lowercase() + val correspondentEmail = email.lowercase() + + val isRealMe = userEmail == correspondentEmail + + val splittedEmail = userEmail?.split("@") + val start = splittedEmail?.first() + "+" + val end = "@" + splittedEmail?.last() + val isPlusMe = correspondentEmail.startsWith(start) && correspondentEmail.endsWith(end) + + return isRealMe || isPlusMe + } fun shouldDisplayUserAvatar(): Boolean = isMe() && email.lowercase() == AccountUtils.currentUser?.email?.lowercase() diff --git a/app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt b/app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt index eac639afde..f3ea247589 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt @@ -1150,7 +1150,7 @@ class MainViewModel @Inject constructor( message != null -> { message.folder.role } - threads?.firstOrNull()?.folder?.id == FolderController.SEARCH_FOLDER_ID -> { + threads?.firstOrNull()?.folderId == FolderController.SEARCH_FOLDER_ID -> { folderController.getFolder(threads.first().folderId)?.role } else -> { From 000a30c4decbc18f4b96b32ef581afa67af095df Mon Sep 17 00:00:00 2001 From: Kevin Boulongne Date: Mon, 3 Mar 2025 18:11:18 +0100 Subject: [PATCH 2/3] refactor: Factorize use of `getStartAndEndOfPlusEmail()` --- .../mail/data/cache/mailboxContent/MessageController.kt | 5 ++--- .../mail/data/models/correspondent/Correspondent.kt | 5 ++--- .../com/infomaniak/mail/utils/extensions/Extensions.kt | 7 +++++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt index e50b56fcbe..b117c4355b 100644 --- a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt +++ b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt @@ -27,6 +27,7 @@ import com.infomaniak.mail.data.models.thread.Thread import com.infomaniak.mail.data.models.thread.Thread.ThreadFilter import com.infomaniak.mail.utils.AccountUtils import com.infomaniak.mail.utils.LocalStorageUtils.deleteDraftUploadDir +import com.infomaniak.mail.utils.extensions.getStartAndEndOfPlusEmail import io.realm.kotlin.MutableRealm import io.realm.kotlin.Realm import io.realm.kotlin.TypedRealm @@ -63,9 +64,7 @@ class MessageController @Inject constructor(private val mailboxContentRealm: Rea val isNotFromRealMe = "SUBQUERY(${Message::from.name}, \$recipient, " + "\$recipient.${Recipient::email.name} != '${AccountUtils.currentMailboxEmail}').@count > 0" - val splittedEmail = AccountUtils.currentMailboxEmail?.split("@") - val start = splittedEmail?.first() + "+" - val end = "@" + splittedEmail?.last() + val (start, end) = AccountUtils.currentMailboxEmail.getStartAndEndOfPlusEmail() val isNotFromPlusMe = "SUBQUERY(${Message::from.name}, \$recipient," + " \$recipient.${Recipient::email.name} BEGINSWITH '${start}'" + " AND \$recipient.${Recipient::email.name} ENDSWITH '${end}'" + diff --git a/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt b/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt index d485a30302..1cba83f6a2 100644 --- a/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt +++ b/app/src/main/java/com/infomaniak/mail/data/models/correspondent/Correspondent.kt @@ -22,6 +22,7 @@ import android.os.Parcelable import com.infomaniak.lib.core.utils.firstOrEmpty import com.infomaniak.mail.R import com.infomaniak.mail.utils.AccountUtils +import com.infomaniak.mail.utils.extensions.getStartAndEndOfPlusEmail import io.sentry.Sentry interface Correspondent : Parcelable { @@ -36,9 +37,7 @@ interface Correspondent : Parcelable { val isRealMe = userEmail == correspondentEmail - val splittedEmail = userEmail?.split("@") - val start = splittedEmail?.first() + "+" - val end = "@" + splittedEmail?.last() + val (start, end) = userEmail.getStartAndEndOfPlusEmail() val isPlusMe = correspondentEmail.startsWith(start) && correspondentEmail.endsWith(end) return isRealMe || isPlusMe diff --git a/app/src/main/java/com/infomaniak/mail/utils/extensions/Extensions.kt b/app/src/main/java/com/infomaniak/mail/utils/extensions/Extensions.kt index aa8a8a83ba..ce0b9af341 100644 --- a/app/src/main/java/com/infomaniak/mail/utils/extensions/Extensions.kt +++ b/app/src/main/java/com/infomaniak/mail/utils/extensions/Extensions.kt @@ -143,6 +143,13 @@ fun String.removeLineBreaksFromHtml(): Document = jsoupParseWithLog(replace("\r" fun String.htmlToText(): String = removeLineBreaksFromHtml().wholeText() +fun String?.getStartAndEndOfPlusEmail(): Pair { + val splittedEmail = this?.split("@") + val fromStartToPlus = splittedEmail?.first() + "+" + val fromArobaseToEnd = "@" + splittedEmail?.last() + return fromStartToPlus to fromArobaseToEnd +} + //region Date fun RealmInstant.toDate(): Date = Date(epochSeconds * 1_000L + nanosecondsOfSecond / 1_000L) From 9b8458a6e969dc4cb0d44f4b2326e849d8bf51e0 Mon Sep 17 00:00:00 2001 From: Kevin Boulongne Date: Tue, 4 Mar 2025 09:24:50 +0100 Subject: [PATCH 3/3] fix: Queries were inverted, so it was involuntarily working. It's fixed now. --- .../mail/data/cache/mailboxContent/MessageController.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt index b117c4355b..6c76f8fd83 100644 --- a/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt +++ b/app/src/main/java/com/infomaniak/mail/data/cache/mailboxContent/MessageController.kt @@ -68,9 +68,9 @@ class MessageController @Inject constructor(private val mailboxContentRealm: Rea val isNotFromPlusMe = "SUBQUERY(${Message::from.name}, \$recipient," + " \$recipient.${Recipient::email.name} BEGINSWITH '${start}'" + " AND \$recipient.${Recipient::email.name} ENDSWITH '${end}'" + - ").@count > 0" + ").@count < 1" - return messages.query("$isNotDraft AND $isNotScheduledDraft AND ($isNotFromRealMe OR $isNotFromPlusMe)").find().lastOrNull() + return messages.query("$isNotDraft AND $isNotScheduledDraft AND $isNotFromRealMe AND $isNotFromPlusMe").find().lastOrNull() ?: messages.query("$isNotDraft AND $isNotScheduledDraft").find().lastOrNull() ?: messages.query(isNotScheduledDraft).find().lastOrNull() ?: messages.last()