Ignore local calendar applying changes to prevent duplicate operations.
This commit is contained in:
@@ -963,6 +963,15 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
|
||||
base.OnCalendarItemUpdated(calendarItem, source);
|
||||
Debug.WriteLine($"Calendar item updated: {calendarItem.Id}");
|
||||
|
||||
// Local-only calendar operations are persisted immediately without real network I/O.
|
||||
// Ignore optimistic client updates to prevent applying the same mutation twice.
|
||||
var isLocalCalendarUpdate = string.IsNullOrWhiteSpace(calendarItem.RemoteEventId) ||
|
||||
calendarItem.RemoteEventId.StartsWith("local-", StringComparison.OrdinalIgnoreCase);
|
||||
if (isLocalCalendarUpdate && source == CalendarItemUpdateSource.ClientUpdated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Series master events should not be visible on the UI.
|
||||
if (calendarItem.IsRecurringParent)
|
||||
{
|
||||
|
||||
@@ -704,9 +704,12 @@ public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreatio
|
||||
// This is important to reflect changes to the UI before the network call is done.
|
||||
|
||||
foreach (var item in batchedRequests)
|
||||
{
|
||||
if (ShouldApplyOptimisticUIChanges(item.Request))
|
||||
{
|
||||
item.Request.ApplyUIChanges();
|
||||
}
|
||||
}
|
||||
|
||||
// All task bundles will execute on the same client.
|
||||
// Tasks themselves don't pull the client from the pool
|
||||
@@ -734,7 +737,10 @@ public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreatio
|
||||
// Client pool failed to get a client.
|
||||
// Requests may not be executed at this point.
|
||||
|
||||
if (ShouldApplyOptimisticUIChanges(item.Request))
|
||||
{
|
||||
item.Request.RevertUIChanges();
|
||||
}
|
||||
|
||||
isCrashed = true;
|
||||
throw;
|
||||
@@ -767,8 +773,11 @@ public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreatio
|
||||
var handled = await _errorHandlerFactory.HandleErrorAsync(errorContext).ConfigureAwait(false);
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
if (ShouldApplyOptimisticUIChanges(item.Request))
|
||||
{
|
||||
item.Request.RevertUIChanges();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -782,6 +791,21 @@ public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreatio
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldApplyOptimisticUIChanges(IRequestBase request)
|
||||
{
|
||||
// Mail changes are always applied.
|
||||
// Calendar changes are applied only if calendar is not in local mode.
|
||||
// Database updates are immidiate and will be reflected in the UI right after the request is processed, so no need for optimistic changes.
|
||||
|
||||
if (request is not ICalendarActionRequest)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var mode = Account.ServerInformation?.CalendarSupportMode ?? ImapCalendarSupportMode.Disabled;
|
||||
return mode != ImapCalendarSupportMode.LocalOnly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns special folder type for the given local folder.
|
||||
/// If server doesn't support special folders, we can't determine the type. MailKit will throw for GetFolder.
|
||||
|
||||
Reference in New Issue
Block a user