Make core library aot compatible.
This commit is contained in:
@@ -253,7 +253,7 @@ public class GmailChangeProcessor : DefaultChangeProcessor, IGmailChangeProcesso
|
||||
}
|
||||
|
||||
// Upsert the event.
|
||||
await Connection.InsertOrReplaceAsync(existingCalendarItem);
|
||||
await Connection.InsertOrReplaceAsync(existingCalendarItem, typeof(CalendarItem));
|
||||
}
|
||||
|
||||
private string GetOrganizerName(Event calendarEvent, MailAccount account)
|
||||
|
||||
@@ -132,7 +132,7 @@ public class OutlookChangeProcessor(IDatabaseService databaseService,
|
||||
}
|
||||
|
||||
// Upsert the event.
|
||||
await Connection.InsertOrReplaceAsync(savingItem);
|
||||
await Connection.InsertOrReplaceAsync(savingItem, typeof(CalendarItem));
|
||||
|
||||
// Manage attendees.
|
||||
if (calendarEvent.Attendees != null)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -21,12 +21,10 @@ public record HttpRequestBundle<TRequest>(TRequest NativeRequest, IUIChangeReque
|
||||
/// <param name="BatchRequest">Batch request that is generated by base synchronizer.</param>
|
||||
public record HttpRequestBundle<TRequest, TResponse>(TRequest NativeRequest, IRequestBase Request) : HttpRequestBundle<TRequest>(NativeRequest, Request)
|
||||
{
|
||||
[RequiresDynamicCode("AOT")]
|
||||
[RequiresUnreferencedCode("AOT")]
|
||||
public async Task<TResponse> DeserializeBundleAsync(HttpResponseMessage httpResponse, CancellationToken cancellationToken = default)
|
||||
public async Task<TResponse> DeserializeBundleAsync(HttpResponseMessage httpResponse, JsonTypeInfo<TResponse> typeInfo, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
return JsonSerializer.Deserialize<TResponse>(content) ?? throw new InvalidOperationException("Invalid Http Response Deserialization");
|
||||
return JsonSerializer.Deserialize(content, typeInfo) ?? throw new InvalidOperationException("Invalid Http Response Deserialization");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
@@ -42,6 +43,11 @@ using CalendarService = Google.Apis.Calendar.v3.CalendarService;
|
||||
|
||||
namespace Wino.Core.Synchronizers.Mail;
|
||||
|
||||
[JsonSerializable(typeof(Message))]
|
||||
[JsonSerializable(typeof(Label))]
|
||||
[JsonSerializable(typeof(Draft))]
|
||||
public partial class GmailSynchronizerJsonContext : JsonSerializerContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gmail synchronizer implementation with per-folder history ID synchronization.
|
||||
///
|
||||
@@ -190,7 +196,7 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
|
||||
// Get all folders to synchronize
|
||||
var synchronizationFolders = await _gmailChangeProcessor.GetSynchronizationFoldersAsync(options).ConfigureAwait(false);
|
||||
|
||||
|
||||
_logger.Information("Synchronizing {Count} folders for {Name}", synchronizationFolders.Count, Account.Name);
|
||||
|
||||
var totalFolders = synchronizationFolders.Count;
|
||||
@@ -1132,12 +1138,12 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
try
|
||||
{
|
||||
MimeMessage mimeMessage = null;
|
||||
|
||||
|
||||
// Extract MIME if we downloaded raw format
|
||||
if (downloadRawMime)
|
||||
{
|
||||
mimeMessage = gmailMessage.GetGmailMimeMessage();
|
||||
|
||||
|
||||
if (mimeMessage == null)
|
||||
{
|
||||
_logger.Warning("Failed to parse MIME for message {MessageId}", gmailMessage.Id);
|
||||
@@ -1152,17 +1158,17 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
// For Gmail, multiple packages can share the same message (different labels/folders)
|
||||
// They should all share the same FileId so MIME is stored only once
|
||||
Guid sharedFileId = Guid.NewGuid();
|
||||
|
||||
|
||||
foreach (var package in packages)
|
||||
{
|
||||
// Set the same FileId for all copies
|
||||
package.Copy.FileId = sharedFileId;
|
||||
|
||||
|
||||
// Create the mail copy with the MIME (if downloaded)
|
||||
var packageWithMime = downloadRawMime && mimeMessage != null
|
||||
? new NewMailItemPackage(package.Copy, mimeMessage, package.AssignedRemoteFolderId)
|
||||
: package;
|
||||
|
||||
|
||||
await _gmailChangeProcessor.CreateMailAsync(Account.Id, packageWithMime).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -1367,7 +1373,7 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
|
||||
if (bundle is HttpRequestBundle<IClientServiceRequest, Message> messageBundle)
|
||||
{
|
||||
var gmailMessage = await messageBundle.DeserializeBundleAsync(httpResponseMessage, cancellationToken).ConfigureAwait(false);
|
||||
var gmailMessage = await messageBundle.DeserializeBundleAsync(httpResponseMessage, GmailSynchronizerJsonContext.Default.Message, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (gmailMessage == null) return;
|
||||
|
||||
@@ -1392,7 +1398,7 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
{
|
||||
// New draft mail is created.
|
||||
|
||||
var messageDraft = await draftBundle.DeserializeBundleAsync(httpResponseMessage, cancellationToken).ConfigureAwait(false);
|
||||
var messageDraft = await draftBundle.DeserializeBundleAsync(httpResponseMessage, GmailSynchronizerJsonContext.Default.Draft, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (messageDraft == null) return;
|
||||
|
||||
|
||||
@@ -137,7 +137,6 @@ public abstract class ImapSynchronizationStrategyBase : IImapSynchronizerStrateg
|
||||
|
||||
foreach (var uniqueId in uniqueIds)
|
||||
{
|
||||
if (uniqueId == null) continue;
|
||||
var localMailCopyId = MailkitClientExtensions.CreateUid(Folder.Id, uniqueId.Id);
|
||||
|
||||
await MailService.DeleteMailAsync(Folder.MailAccountId, localMailCopyId).ConfigureAwait(false);
|
||||
|
||||
@@ -34,10 +34,11 @@ namespace Wino.Core.Synchronizers.Mail;
|
||||
|
||||
public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreationPackage, object>, IImapSynchronizer
|
||||
{
|
||||
[Obsolete("N/A")]
|
||||
/// <summary>
|
||||
/// N/A for IMAP as it doesn't support batch modifications natively.
|
||||
/// </summary>
|
||||
public override uint BatchModificationSize => 1000;
|
||||
public override uint InitialMessageDownloadCountPerFolder => 500;
|
||||
public override int InitialSyncMimeDownloadCount => 50;
|
||||
|
||||
#region Idle Implementation
|
||||
|
||||
@@ -313,7 +314,7 @@ public class ImapSynchronizer : WinoSynchronizer<ImapRequest, ImapMessageCreatio
|
||||
for (int i = 0; i < totalFolders; i++)
|
||||
{
|
||||
var folder = synchronizationFolders[i];
|
||||
|
||||
|
||||
// Update progress based on folder completion
|
||||
UpdateSyncProgress(totalFolders, totalFolders - (i + 1), $"Syncing {folder.FolderName}...");
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
@@ -574,23 +573,23 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
{
|
||||
// This message belongs to existing local draft copy.
|
||||
// We don't need to create a new mail copy for this message, just update the existing one.
|
||||
|
||||
|
||||
bool isMappingSuccessful = await _outlookChangeProcessor.MapLocalDraftAsync(
|
||||
Account.Id,
|
||||
localDraftCopyUniqueId,
|
||||
mailCopy.Id,
|
||||
mailCopy.DraftId,
|
||||
Account.Id,
|
||||
localDraftCopyUniqueId,
|
||||
mailCopy.Id,
|
||||
mailCopy.DraftId,
|
||||
mailCopy.ThreadId);
|
||||
|
||||
if (isMappingSuccessful)
|
||||
{
|
||||
_logger.Debug("Successfully mapped remote draft {RemoteId} to local draft {LocalId}",
|
||||
_logger.Debug("Successfully mapped remote draft {RemoteId} to local draft {LocalId}",
|
||||
mailCopy.Id, localDraftCopyUniqueId);
|
||||
return null; // Don't create new mail copy, existing one was updated
|
||||
}
|
||||
|
||||
// Local copy doesn't exist. Continue execution to insert mail copy.
|
||||
_logger.Debug("Local draft copy {LocalId} not found, creating new mail copy for {RemoteId}",
|
||||
_logger.Debug("Local draft copy {LocalId} not found, creating new mail copy for {RemoteId}",
|
||||
localDraftCopyUniqueId, mailCopy.Id);
|
||||
}
|
||||
}
|
||||
@@ -875,7 +874,6 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
await UpdateDeltaSynchronizationIdentifierAsync(iterator.Deltalink).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[RequiresUnreferencedCode("Calls Microsoft.Kiota.Abstractions.Serialization.KiotaJsonSerializer.DeserializeAsync<T>(String, CancellationToken)")]
|
||||
private async Task<T> DeserializeGraphBatchResponseAsync<T>(BatchResponseContentCollection collection, string requestId, CancellationToken cancellationToken = default) where T : IParsable, new()
|
||||
{
|
||||
// This deserialization may throw generalException in case of failure.
|
||||
@@ -893,12 +891,12 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
// TODO: AOT Comaptible inner exception deserialization.
|
||||
|
||||
// Actual exception is hidden inside ServiceException.
|
||||
// ODataError errorResult = await KiotaJsonSerializer.DeserializeAsync<ODataError>(serviceException.RawResponseBody, cancellationToken);
|
||||
|
||||
|
||||
ODataError errorResult = await KiotaJsonSerializer.DeserializeAsync<ODataError>(serviceException.RawResponseBody, cancellationToken);
|
||||
|
||||
throw new SynchronizerException("Outlook Error", errorResult);
|
||||
throw new SynchronizerException("Outlook Error", serviceException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,14 +45,6 @@ public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEven
|
||||
/// </summary>
|
||||
public abstract uint InitialMessageDownloadCountPerFolder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// DEPRECATED: MIME messages are no longer downloaded during synchronization.
|
||||
/// MIME content is only downloaded when explicitly needed (e.g., when user reads a message).
|
||||
/// This property is kept for backward compatibility but is no longer used.
|
||||
/// </summary>
|
||||
[Obsolete("MIME messages are no longer downloaded during sync. Use DownloadMissingMimeMessageAsync instead.")]
|
||||
public virtual int InitialSyncMimeDownloadCount => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Wino Mail Item package out of native message type with metadata only.
|
||||
/// NO MIME content is downloaded during synchronization - only headers and essential metadata.
|
||||
|
||||
Reference in New Issue
Block a user