Skip to content

Commit

Permalink
feat: Handle updated uids for snooze
Browse files Browse the repository at this point in the history
  • Loading branch information
LunarX authored and KevinBoulongne committed Mar 6, 2025
1 parent abb7b41 commit f52940f
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import com.infomaniak.mail.data.models.draft.SaveDraftResult
import com.infomaniak.mail.data.models.draft.ScheduleDraftResult
import com.infomaniak.mail.data.models.draft.SendDraftResult
import com.infomaniak.mail.data.models.getMessages.ActivitiesResult
import com.infomaniak.mail.data.models.getMessages.CommonMessageFlags
import com.infomaniak.mail.data.models.getMessages.GetMessagesByUidsResult
import com.infomaniak.mail.data.models.getMessages.NewMessagesResult
import com.infomaniak.mail.data.models.mailbox.Mailbox
Expand Down Expand Up @@ -283,12 +284,12 @@ object ApiRepository : ApiRepositoryCore() {
)
}

fun getMessagesUidsDelta(
inline fun <reified T: CommonMessageFlags> getMessagesUidsDelta(
mailboxUuid: String,
folderId: String,
cursor: String,
okHttpClient: OkHttpClient?,
): ApiResponse<ActivitiesResult> {
): ApiResponse<ActivitiesResult<T>> {
return callApi(
url = ApiRoutes.getMessagesUidsDelta(mailboxUuid, folderId, cursor),
method = GET,
Expand Down
44 changes: 44 additions & 0 deletions app/src/main/java/com/infomaniak/mail/data/api/DateSerializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2022-2025 Infomaniak Network SA
*
* 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.infomaniak.mail.data.api

import com.infomaniak.core.utils.FORMAT_DATE_WITH_TIMEZONE
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

object DateSerializer : KSerializer<Date> {

private val simpleDateFormat = SimpleDateFormat(FORMAT_DATE_WITH_TIMEZONE, Locale.ROOT)

override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): Date {
return simpleDateFormat.parse(decoder.decodeString()) ?: Date(Long.MAX_VALUE)
}

override fun serialize(encoder: Encoder, value: Date) {
value.let(simpleDateFormat::format).let(encoder::encodeString)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ import com.infomaniak.mail.data.cache.mailboxContent.RefreshController.RefreshMo
import com.infomaniak.mail.data.cache.mailboxInfo.MailboxController
import com.infomaniak.mail.data.models.Folder
import com.infomaniak.mail.data.models.Folder.FolderRole
import com.infomaniak.mail.data.models.getMessages.ActivitiesResult
import com.infomaniak.mail.data.models.getMessages.ActivitiesResult.MessageFlags
import com.infomaniak.mail.data.models.getMessages.NewMessagesResult
import com.infomaniak.mail.data.models.getMessages.*
import com.infomaniak.mail.data.models.mailbox.Mailbox
import com.infomaniak.mail.data.models.message.Message
import com.infomaniak.mail.data.models.message.Message.MessageInitialState
Expand Down Expand Up @@ -256,8 +254,11 @@ class RefreshController @Inject constructor(
}

private suspend fun Realm.fetchActivities(scope: CoroutineScope, folder: Folder, previousCursor: String) {
val activities = when (folder.role) {
FolderRole.SNOOZED -> getMessagesUidsDelta<SnoozeMessageFlags>(folder.id, previousCursor)
else -> getMessagesUidsDelta<MessageFlags>(folder.id, previousCursor)
} ?: return

val activities = getMessagesUidsDelta(folder.id, previousCursor) ?: return
scope.ensureActive()

val logMessage = "Deleted: ${activities.deletedShortUids.count()} | " +
Expand Down Expand Up @@ -475,7 +476,7 @@ class RefreshController @Inject constructor(
//region Updated Messages
private fun MutableRealm.handleUpdatedUids(
scope: CoroutineScope,
messageFlags: List<MessageFlags>,
messageFlags: List<CommonMessageFlags>,
folderId: String,
refreshStrategy: RefreshStrategy,
): ImpactedFolders {
Expand All @@ -484,7 +485,10 @@ class RefreshController @Inject constructor(
scope.ensureActive()

refreshStrategy.getMessageFromShortUid(flags.shortUid, folderId, realm = this)?.let { message ->
message.updateFlags(flags)
when (flags) {
is MessageFlags -> message.updateFlags(flags)
is SnoozeMessageFlags -> message.updateSnoozeFlags(flags)
}
threads += message.threads
}
}
Expand Down Expand Up @@ -556,8 +560,8 @@ class RefreshController @Inject constructor(
}
}

private fun getMessagesUidsDelta(folderId: String, previousCursor: String): ActivitiesResult? {
return with(ApiRepository.getMessagesUidsDelta(mailbox.uuid, folderId, previousCursor, okHttpClient)) {
private inline fun <reified T : CommonMessageFlags> getMessagesUidsDelta(folderId: String, previousCursor: String): ActivitiesResult<T>? {
return with(ApiRepository.getMessagesUidsDelta<T>(mailbox.uuid, folderId, previousCursor, okHttpClient)) {
if (!isSuccess()) throwErrorAsException()
return@with data
}
Expand Down Expand Up @@ -595,7 +599,7 @@ class RefreshController @Inject constructor(
logMessage: String,
email: String,
folder: Folder,
activities: ActivitiesResult,
activities: ActivitiesResult<out CommonMessageFlags>,
) {
SentryDebug.addThreadsAlgoBreadcrumb(
message = logMessage,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2022-2024 Infomaniak Network SA
* Copyright (C) 2022-2025 Infomaniak Network SA
*
* 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
Expand All @@ -21,31 +21,15 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ActivitiesResult(
data class ActivitiesResult<T : CommonMessageFlags>(
@SerialName("deleted")
val deletedShortUids: List<String>,
@SerialName("updated")
val updatedMessages: List<MessageFlags>,
val updatedMessages: List<T>,
@SerialName("added")
val addedShortUids: List<Int>,
@SerialName("unread_count")
val unreadCountRemote: Int,
@SerialName("signature")
val cursor: String,
) {
@Serializable
data class MessageFlags(
@SerialName("uid")
val shortUid: String,
@SerialName("answered")
val isAnswered: Boolean,
@SerialName("flagged")
val isFavorite: Boolean,
@SerialName("forwarded")
val isForwarded: Boolean,
@SerialName("scheduled")
val isScheduledMessage: Boolean,
@SerialName("seen")
val isSeen: Boolean,
)
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2025 Infomaniak Network SA
*
* 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.infomaniak.mail.data.models.getMessages

sealed interface CommonMessageFlags {
val shortUid: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2025 Infomaniak Network SA
*
* 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.infomaniak.mail.data.models.getMessages

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class MessageFlags(
@SerialName("uid")
override val shortUid: String,
@SerialName("answered")
val isAnswered: Boolean,
@SerialName("flagged")
val isFavorite: Boolean,
@SerialName("forwarded")
val isForwarded: Boolean,
@SerialName("scheduled")
val isScheduledMessage: Boolean,
@SerialName("seen")
val isSeen: Boolean,
) : CommonMessageFlags
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2025 Infomaniak Network SA
*
* 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/>.
*/
@file:UseSerializers(DateSerializer::class)
/*
* Infomaniak Mail - Android
* Copyright (C) 2025 Infomaniak Network SA
*
* 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.infomaniak.mail.data.models.getMessages

import com.infomaniak.mail.data.api.DateSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import java.util.Date

@Serializable
data class SnoozeMessageFlags(
@SerialName("uid")
override val shortUid: String,
@SerialName("snooze_end_date")
val snoozeEndDate: Date,
): CommonMessageFlags
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import com.infomaniak.mail.data.models.SnoozeState
import com.infomaniak.mail.data.models.SwissTransferFile
import com.infomaniak.mail.data.models.calendar.CalendarEventResponse
import com.infomaniak.mail.data.models.correspondent.Recipient
import com.infomaniak.mail.data.models.getMessages.ActivitiesResult.MessageFlags
import com.infomaniak.mail.data.models.getMessages.MessageFlags
import com.infomaniak.mail.data.models.getMessages.SnoozeMessageFlags
import com.infomaniak.mail.data.models.thread.Thread
import com.infomaniak.mail.utils.AccountUtils
import com.infomaniak.mail.utils.MessageBodyUtils.SplitBody
Expand Down Expand Up @@ -337,6 +338,10 @@ class Message : RealmObject {
isScheduledMessage = flags.isScheduledMessage
}

fun updateSnoozeFlags(flags: SnoozeMessageFlags) {
snoozeEndDate = flags.snoozeEndDate.toRealmInstant()
}

fun shouldBeExpanded(index: Int, lastIndex: Int) = !isDraft && (!isSeen || index == lastIndex)

fun toThread() = Thread().apply {
Expand Down

0 comments on commit f52940f

Please sign in to comment.