diff --git a/Wino.Core.Domain/Enums/MailUpdateSource.cs b/Wino.Core.Domain/Enums/MailUpdateSource.cs
new file mode 100644
index 00000000..4e5b86bf
--- /dev/null
+++ b/Wino.Core.Domain/Enums/MailUpdateSource.cs
@@ -0,0 +1,17 @@
+namespace Wino.Core.Domain.Enums;
+
+///
+/// Indicates the source of a mail update.
+///
+public enum MailUpdateSource
+{
+ ///
+ /// Update originated from client-side UI changes (ApplyUIChanges/RevertUIChanges).
+ ///
+ Client,
+
+ ///
+ /// Update originated from server synchronization or database operations.
+ ///
+ Server
+}
diff --git a/Wino.Core/Requests/Folder/MarkFolderAsReadRequest.cs b/Wino.Core/Requests/Folder/MarkFolderAsReadRequest.cs
index 74ffa5eb..1c0e4f4b 100644
--- a/Wino.Core/Requests/Folder/MarkFolderAsReadRequest.cs
+++ b/Wino.Core/Requests/Folder/MarkFolderAsReadRequest.cs
@@ -17,7 +17,7 @@ public record MarkFolderAsReadRequest(MailItemFolder Folder, List Mail
{
item.IsRead = true;
- WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(item));
+ WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(item, MailUpdateSource.Client));
}
}
@@ -27,7 +27,7 @@ public record MarkFolderAsReadRequest(MailItemFolder Folder, List Mail
{
item.IsRead = false;
- WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(item));
+ WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(item, MailUpdateSource.Client));
}
}
diff --git a/Wino.Core/Requests/Mail/ChangeFlagRequest.cs b/Wino.Core/Requests/Mail/ChangeFlagRequest.cs
index 8410cd8e..4ae4800c 100644
--- a/Wino.Core/Requests/Mail/ChangeFlagRequest.cs
+++ b/Wino.Core/Requests/Mail/ChangeFlagRequest.cs
@@ -22,14 +22,14 @@ public record ChangeFlagRequest(MailCopy Item, bool IsFlagged) : MailRequestBase
{
Item.IsFlagged = IsFlagged;
- WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item));
+ WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item, MailUpdateSource.Client));
}
public override void RevertUIChanges()
{
Item.IsFlagged = !IsFlagged;
- WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item));
+ WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item, MailUpdateSource.Client));
}
}
diff --git a/Wino.Core/Requests/Mail/MarkReadRequest.cs b/Wino.Core/Requests/Mail/MarkReadRequest.cs
index fded7f8b..046aee01 100644
--- a/Wino.Core/Requests/Mail/MarkReadRequest.cs
+++ b/Wino.Core/Requests/Mail/MarkReadRequest.cs
@@ -21,14 +21,14 @@ public record MarkReadRequest(MailCopy Item, bool IsRead) : MailRequestBase(Item
{
Item.IsRead = IsRead;
- WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item));
+ WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item, MailUpdateSource.Client));
}
public override void RevertUIChanges()
{
Item.IsRead = !IsRead;
- WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item));
+ WeakReferenceMessenger.Default.Send(new MailUpdatedMessage(Item, MailUpdateSource.Client));
}
}
diff --git a/Wino.Mail.ViewModels/ComposePageViewModel.cs b/Wino.Mail.ViewModels/ComposePageViewModel.cs
index bb790860..f558f308 100644
--- a/Wino.Mail.ViewModels/ComposePageViewModel.cs
+++ b/Wino.Mail.ViewModels/ComposePageViewModel.cs
@@ -633,9 +633,9 @@ public partial class ComposePageViewModel : MailBaseViewModel
_dialogService.InfoBarMessage(Translator.Info_InvalidAddressTitle, string.Format(Translator.Info_InvalidAddressMessage, address), InfoBarMessageType.Warning);
}
- protected override async void OnMailUpdated(MailCopy updatedMail)
+ protected override async void OnMailUpdated(MailCopy updatedMail, MailUpdateSource source)
{
- base.OnMailUpdated(updatedMail);
+ base.OnMailUpdated(updatedMail, source);
if (CurrentMailDraftItem == null) return;
diff --git a/Wino.Mail.ViewModels/MailBaseViewModel.cs b/Wino.Mail.ViewModels/MailBaseViewModel.cs
index e27324ce..53646754 100644
--- a/Wino.Mail.ViewModels/MailBaseViewModel.cs
+++ b/Wino.Mail.ViewModels/MailBaseViewModel.cs
@@ -1,6 +1,7 @@
using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
+using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Folders;
using Wino.Core.ViewModels;
using Wino.Messaging.UI;
@@ -20,7 +21,7 @@ public class MailBaseViewModel : CoreBaseViewModel,
{
protected virtual void OnMailAdded(MailCopy addedMail) { }
protected virtual void OnMailRemoved(MailCopy removedMail) { }
- protected virtual void OnMailUpdated(MailCopy updatedMail) { }
+ protected virtual void OnMailUpdated(MailCopy updatedMail, MailUpdateSource source) { }
protected virtual void OnMailDownloaded(MailCopy downloadedMail) { }
protected virtual void OnDraftCreated(MailCopy draftMail, MailAccount account) { }
protected virtual void OnDraftFailed(MailCopy draftMail, MailAccount account) { }
@@ -30,7 +31,7 @@ public class MailBaseViewModel : CoreBaseViewModel,
void IRecipient.Receive(MailAddedMessage message) => OnMailAdded(message.AddedMail);
void IRecipient.Receive(MailRemovedMessage message) => OnMailRemoved(message.RemovedMail);
- void IRecipient.Receive(MailUpdatedMessage message) => OnMailUpdated(message.UpdatedMail);
+ void IRecipient.Receive(MailUpdatedMessage message) => OnMailUpdated(message.UpdatedMail, message.Source);
void IRecipient.Receive(MailDownloadedMessage message) => OnMailDownloaded(message.DownloadedMail);
void IRecipient.Receive(DraftMapped message) => OnDraftMapped(message.LocalDraftCopyId, message.RemoteDraftCopyId);
diff --git a/Wino.Mail.ViewModels/MailListPageViewModel.cs b/Wino.Mail.ViewModels/MailListPageViewModel.cs
index c8905d51..27139c2f 100644
--- a/Wino.Mail.ViewModels/MailListPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailListPageViewModel.cs
@@ -664,9 +664,9 @@ public partial class MailListPageViewModel : MailBaseViewModel,
}
}
- protected override async void OnMailUpdated(MailCopy updatedMail)
+ protected override async void OnMailUpdated(MailCopy updatedMail, MailUpdateSource source)
{
- base.OnMailUpdated(updatedMail);
+ base.OnMailUpdated(updatedMail, source);
await MailCollection.UpdateMailCopy(updatedMail);
diff --git a/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs b/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
index bc14d954..5c6a51b2 100644
--- a/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
+++ b/Wino.Mail.ViewModels/MailRenderingPageViewModel.cs
@@ -618,9 +618,9 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MarkAsRead, true, false));
}
- protected override async void OnMailUpdated(MailCopy updatedMail)
+ protected override async void OnMailUpdated(MailCopy updatedMail, MailUpdateSource source)
{
- base.OnMailUpdated(updatedMail);
+ base.OnMailUpdated(updatedMail, source);
if (initializedMailItemViewModel == null) return;
diff --git a/Wino.Messages/UI/MailUpdatedMessage.cs b/Wino.Messages/UI/MailUpdatedMessage.cs
index b0c140e2..546a8d9d 100644
--- a/Wino.Messages/UI/MailUpdatedMessage.cs
+++ b/Wino.Messages/UI/MailUpdatedMessage.cs
@@ -1,5 +1,6 @@
using Wino.Core.Domain.Entities.Mail;
+using Wino.Core.Domain.Enums;
namespace Wino.Messaging.UI;
-public record MailUpdatedMessage(MailCopy UpdatedMail) : UIMessageBase;
+public record MailUpdatedMessage(MailCopy UpdatedMail, MailUpdateSource Source) : UIMessageBase;
diff --git a/Wino.Services/MailService.cs b/Wino.Services/MailService.cs
index 6a1e3008..e338f680 100644
--- a/Wino.Services/MailService.cs
+++ b/Wino.Services/MailService.cs
@@ -543,7 +543,7 @@ public class MailService : BaseDatabaseService, IMailService
await Connection.UpdateAsync(mailCopy, typeof(MailCopy)).ConfigureAwait(false);
- ReportUIChange(new MailUpdatedMessage(mailCopy));
+ ReportUIChange(new MailUpdatedMessage(mailCopy, MailUpdateSource.Server));
}
private async Task DeleteMailInternalAsync(MailCopy mailCopy, bool preserveMimeFile)