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 f3ea247589..b3b1ceb7f2 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt @@ -30,12 +30,9 @@ import com.infomaniak.mail.R import com.infomaniak.mail.data.LocalSettings import com.infomaniak.mail.data.api.ApiRepository import com.infomaniak.mail.data.cache.RealmDatabase -import com.infomaniak.mail.data.cache.mailboxContent.FolderController -import com.infomaniak.mail.data.cache.mailboxContent.MessageController -import com.infomaniak.mail.data.cache.mailboxContent.RefreshController +import com.infomaniak.mail.data.cache.mailboxContent.* import com.infomaniak.mail.data.cache.mailboxContent.RefreshController.RefreshCallbacks import com.infomaniak.mail.data.cache.mailboxContent.RefreshController.RefreshMode -import com.infomaniak.mail.data.cache.mailboxContent.ThreadController import com.infomaniak.mail.data.cache.mailboxInfo.MailboxController import com.infomaniak.mail.data.cache.mailboxInfo.PermissionsController import com.infomaniak.mail.data.cache.mailboxInfo.QuotasController @@ -552,7 +549,8 @@ class MainViewModel @Inject constructor( threadController.updateIsLocallyMovedOutStatus(threadsUids, hasBeenMovedOut = false) val undoDestinationId = message?.folderId ?: threads.first().folderId - val undoFoldersIds = (messages.getFoldersIds(exception = undoDestinationId) + trashId).filterNotNull() + val undoFoldersIds = messages.getFoldersIds(exception = undoDestinationId) + if (trashId != null) undoFoldersIds += trashId showDeleteSnackbar( apiResponses, shouldPermanentlyDelete, @@ -569,7 +567,7 @@ class MainViewModel @Inject constructor( shouldPermanentlyDelete: Boolean, message: Message?, undoResources: List, - undoFoldersIds: List, + undoFoldersIds: ImpactedFolders, undoDestinationId: String?, numberOfImpactedThreads: Int, ) { @@ -608,7 +606,7 @@ class MainViewModel @Inject constructor( if (apiResponse.isSuccess() && mailbox.uuid == targetMailboxUuid) { val draftFolderId = folderController.getFolder(FolderRole.DRAFT)!!.id - refreshFoldersAsync(mailbox, listOf(draftFolderId)) + refreshFoldersAsync(mailbox, ImpactedFolders(mutableSetOf(draftFolderId))) } showDeletedDraftSnackbar(apiResponse) @@ -626,7 +624,7 @@ class MainViewModel @Inject constructor( with(ApiRepository.rescheduleDraft(resource, scheduleDate)) { if (isSuccess()) { val scheduledDraftsFolderId = folderController.getFolder(FolderRole.SCHEDULED_DRAFTS)!!.id - refreshFoldersAsync(currentMailbox.value!!, listOf(scheduledDraftsFolderId)) + refreshFoldersAsync(currentMailbox.value!!, ImpactedFolders(mutableSetOf(scheduledDraftsFolderId))) } else { snackbarManager.postValue(title = appContext.getString(translatedError)) } @@ -645,7 +643,7 @@ class MainViewModel @Inject constructor( if (apiResponse.isSuccess()) { val scheduledDraftsFolderId = folderController.getFolder(FolderRole.SCHEDULED_DRAFTS)!!.id - refreshFoldersAsync(mailbox, listOf(scheduledDraftsFolderId)) + refreshFoldersAsync(mailbox, ImpactedFolders(mutableSetOf(scheduledDraftsFolderId))) onSuccess() } else { snackbarManager.postValue(title = appContext.getString(apiResponse.translatedError)) @@ -658,7 +656,7 @@ class MainViewModel @Inject constructor( if (apiResponse.isSuccess()) { val scheduledDraftsFolderId = folderController.getFolder(FolderRole.SCHEDULED_DRAFTS)!!.id - refreshFoldersAsync(mailbox, listOf(scheduledDraftsFolderId)) + refreshFoldersAsync(mailbox, ImpactedFolders(mutableSetOf(scheduledDraftsFolderId))) } showUnscheduledDraftSnackbar(apiResponse) @@ -734,9 +732,11 @@ class MainViewModel @Inject constructor( null } else { val undoDestinationId = message?.folderId ?: threads.first().folderId + val foldersIds = messages.getFoldersIds(exception = undoDestinationId) + foldersIds += destinationFolder.id UndoData( resources = apiResponses.mapNotNull { it.data?.undoResource }, - foldersIds = messages.getFoldersIds(exception = undoDestinationId) + destinationFolder.id, + foldersIds = foldersIds, destinationFolderId = undoDestinationId, ) } @@ -1114,7 +1114,7 @@ class MainViewModel @Inject constructor( private fun refreshFoldersAsync( mailbox: Mailbox, - messagesFoldersIds: List, + messagesFoldersIds: ImpactedFolders, destinationFolderId: String? = null, callbacks: RefreshCallbacks? = null, ) = viewModelScope.launch(ioCoroutineContext) { diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/SnackbarManager.kt b/app/src/main/java/com/infomaniak/mail/ui/main/SnackbarManager.kt index 314b017a54..115c4a679d 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/SnackbarManager.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/SnackbarManager.kt @@ -1,6 +1,6 @@ /* * Infomaniak Mail - Android - * Copyright (C) 2023-2024 Infomaniak Network SA + * Copyright (C) 2023-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 @@ -23,6 +23,7 @@ import androidx.fragment.app.FragmentActivity import com.google.android.material.snackbar.Snackbar import com.infomaniak.lib.core.utils.SingleLiveEvent import com.infomaniak.lib.core.utils.SnackbarUtils.showSnackbar +import com.infomaniak.mail.data.cache.mailboxContent.ImpactedFolders import javax.inject.Inject import javax.inject.Singleton import com.infomaniak.lib.core.R as RCore @@ -91,7 +92,7 @@ class SnackbarManager @Inject constructor() { data class UndoData( val resources: List, - val foldersIds: List, + val foldersIds: ImpactedFolders, val destinationFolderId: String?, ) } diff --git a/app/src/main/java/com/infomaniak/mail/utils/SharedUtils.kt b/app/src/main/java/com/infomaniak/mail/utils/SharedUtils.kt index 4da6f0ce5f..87532053ae 100644 --- a/app/src/main/java/com/infomaniak/mail/utils/SharedUtils.kt +++ b/app/src/main/java/com/infomaniak/mail/utils/SharedUtils.kt @@ -24,6 +24,7 @@ import com.infomaniak.mail.R import com.infomaniak.mail.data.LocalSettings import com.infomaniak.mail.data.api.ApiRepository import com.infomaniak.mail.data.cache.RealmDatabase +import com.infomaniak.mail.data.cache.mailboxContent.ImpactedFolders import com.infomaniak.mail.data.cache.mailboxContent.MessageController import com.infomaniak.mail.data.cache.mailboxContent.RefreshController import com.infomaniak.mail.data.cache.mailboxContent.RefreshController.RefreshCallbacks @@ -111,14 +112,15 @@ class SharedUtils @Inject constructor( suspend fun refreshFolders( mailbox: Mailbox, - messagesFoldersIds: List, + messagesFoldersIds: ImpactedFolders, destinationFolderId: String? = null, currentFolderId: String? = null, callbacks: RefreshCallbacks? = null, ) { + val realm = mailboxContentRealm() // We always want to refresh the `destinationFolder` last, to avoid any blink on the UI. - val foldersIds = messagesFoldersIds.toMutableSet() + val foldersIds = messagesFoldersIds.getFolderIds(realm).toMutableSet() destinationFolderId?.let(foldersIds::add) foldersIds.forEach { folderId -> @@ -126,7 +128,7 @@ class SharedUtils @Inject constructor( refreshMode = RefreshMode.REFRESH_FOLDER, mailbox = mailbox, folderId = folderId, - realm = mailboxContentRealm(), + realm = realm, callbacks = if (folderId == currentFolderId) callbacks else null, ) } 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 80964e1e6f..efbec5f4d5 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 @@ -78,9 +78,11 @@ import com.infomaniak.mail.MainApplication import com.infomaniak.mail.R import com.infomaniak.mail.data.LocalSettings.ThreadDensity import com.infomaniak.mail.data.cache.mailboxContent.FolderController +import com.infomaniak.mail.data.cache.mailboxContent.ImpactedFolders import com.infomaniak.mail.data.models.Attachment import com.infomaniak.mail.data.models.Folder import com.infomaniak.mail.data.models.Folder.FolderRole +import com.infomaniak.mail.data.models.SnoozeState import com.infomaniak.mail.data.models.correspondent.Correspondent import com.infomaniak.mail.data.models.correspondent.MergedContact import com.infomaniak.mail.data.models.correspondent.Recipient @@ -409,7 +411,22 @@ fun List.addDividerBeforeFirstCustomFolder(dividerType: Any): List //endregion //region Messages -fun List.getFoldersIds(exception: String? = null) = mapNotNull { if (it.folderId == exception) null else it.folderId } +fun List.getFoldersIds(exception: String? = null): ImpactedFolders { + val impactedFolders = ImpactedFolders() + + forEach { message -> + when { + message.folderId == exception -> Unit + message.snoozeState == SnoozeState.Snoozed -> { + impactedFolders += message.folderId + impactedFolders += FolderRole.SNOOZED + } + else -> impactedFolders += message.folderId + } + } + + return impactedFolders +} fun List.getUids(): List = map { it.uid } //endregion