- Fix for gmail calendar event creation.
- Proper junk API calls for gmail and outlook, not just moving the item. - Add ability to hide ai actions panel.
This commit is contained in:
@@ -9,6 +9,7 @@ public enum MailSynchronizerOperation
|
|||||||
CreateDraft,
|
CreateDraft,
|
||||||
Send,
|
Send,
|
||||||
ChangeFlag,
|
ChangeFlag,
|
||||||
|
ChangeJunkState,
|
||||||
AlwaysMoveTo,
|
AlwaysMoveTo,
|
||||||
MoveToFocused,
|
MoveToFocused,
|
||||||
Archive,
|
Archive,
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ public interface IPreferencesService : INotifyPropertyChanged
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsWinoAccountButtonHidden { get; set; }
|
bool IsWinoAccountButtonHidden { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting: Whether AI actions panels and their toggle buttons should be hidden.
|
||||||
|
/// </summary>
|
||||||
|
bool IsAiActionsPanelHidden { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Setting: Default target language code used for AI translation actions.
|
/// Setting: Default target language code used for AI translation actions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -736,6 +736,8 @@
|
|||||||
"SettingsAppPreferences_HideWinoAccountButton_Description": "Hide the title bar profile button that opens the Wino account flyout.",
|
"SettingsAppPreferences_HideWinoAccountButton_Description": "Hide the title bar profile button that opens the Wino account flyout.",
|
||||||
"SettingsAppPreferences_StoreUpdateNotifications_Title": "Store update notifications",
|
"SettingsAppPreferences_StoreUpdateNotifications_Title": "Store update notifications",
|
||||||
"SettingsAppPreferences_StoreUpdateNotifications_Description": "Show notifications and footer actions when a Microsoft Store update is available.",
|
"SettingsAppPreferences_StoreUpdateNotifications_Description": "Show notifications and footer actions when a Microsoft Store update is available.",
|
||||||
|
"SettingsAppPreferences_HideAiActionsPanel_Title": "Hide AI actions panel",
|
||||||
|
"SettingsAppPreferences_HideAiActionsPanel_Description": "Hide AI actions in the mail composer and reader.",
|
||||||
"SettingsAppPreferences_AiActions_Title": "AI actions",
|
"SettingsAppPreferences_AiActions_Title": "AI actions",
|
||||||
"SettingsAppPreferences_AiActions_Description": "Choose default AI languages and where summaries should be saved.",
|
"SettingsAppPreferences_AiActions_Description": "Choose default AI languages and where summaries should be saved.",
|
||||||
"SettingsAppPreferences_AiDefaultTranslationLanguage_Title": "Default translation language",
|
"SettingsAppPreferences_AiDefaultTranslationLanguage_Title": "Default translation language",
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ public static class SynchronizationActionHelper
|
|||||||
{
|
{
|
||||||
MarkReadRequest r => r.IsRead ? "MarkRead" : "MarkUnread",
|
MarkReadRequest r => r.IsRead ? "MarkRead" : "MarkUnread",
|
||||||
ChangeFlagRequest r => r.IsFlagged ? "SetFlag" : "ClearFlag",
|
ChangeFlagRequest r => r.IsFlagged ? "SetFlag" : "ClearFlag",
|
||||||
|
ChangeJunkStateRequest r => r.IsJunk ? "MarkJunk" : "MarkNotJunk",
|
||||||
ArchiveRequest r => r.IsArchiving ? "Archive" : "Unarchive",
|
ArchiveRequest r => r.IsArchiving ? "Archive" : "Unarchive",
|
||||||
_ => request.Operation.ToString()
|
_ => request.Operation.ToString()
|
||||||
};
|
};
|
||||||
@@ -100,6 +101,8 @@ public static class SynchronizationActionHelper
|
|||||||
"MarkUnread" => string.Format(Translator.SyncAction_MarkingAsUnread, count),
|
"MarkUnread" => string.Format(Translator.SyncAction_MarkingAsUnread, count),
|
||||||
"Delete" => string.Format(Translator.SyncAction_Deleting, count),
|
"Delete" => string.Format(Translator.SyncAction_Deleting, count),
|
||||||
"Move" => string.Format(Translator.SyncAction_Moving, count),
|
"Move" => string.Format(Translator.SyncAction_Moving, count),
|
||||||
|
"MarkJunk" => string.Format(Translator.SyncAction_Moving, count),
|
||||||
|
"MarkNotJunk" => string.Format(Translator.SyncAction_Moving, count),
|
||||||
"Archive" => string.Format(Translator.SyncAction_Archiving, count),
|
"Archive" => string.Format(Translator.SyncAction_Archiving, count),
|
||||||
"Unarchive" => string.Format(Translator.SyncAction_Unarchiving, count),
|
"Unarchive" => string.Format(Translator.SyncAction_Unarchiving, count),
|
||||||
"SetFlag" => string.Format(Translator.SyncAction_SettingFlag, count),
|
"SetFlag" => string.Format(Translator.SyncAction_SettingFlag, count),
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
using Wino.Core.Domain.Enums;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Requests;
|
||||||
|
using Wino.Messaging.UI;
|
||||||
|
|
||||||
|
namespace Wino.Core.Requests.Mail;
|
||||||
|
|
||||||
|
public record ChangeJunkStateRequest(bool IsJunk, MailCopy Item, MailItemFolder FromFolder, MailItemFolder TargetFolder)
|
||||||
|
: MailRequestBase(Item), ICustomFolderSynchronizationRequest
|
||||||
|
{
|
||||||
|
public List<Guid> SynchronizationFolderIds
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var folderIds = new List<Guid> { FromFolder.Id };
|
||||||
|
|
||||||
|
if (TargetFolder != null)
|
||||||
|
{
|
||||||
|
folderIds.Add(TargetFolder.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return folderIds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ExcludeMustHaveFolders => false;
|
||||||
|
|
||||||
|
public override MailSynchronizerOperation Operation => MailSynchronizerOperation.ChangeJunkState;
|
||||||
|
|
||||||
|
public override void ApplyUIChanges()
|
||||||
|
{
|
||||||
|
WeakReferenceMessenger.Default.Send(new MailRemovedMessage(Item, EntityUpdateSource.ClientUpdated));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RevertUIChanges()
|
||||||
|
{
|
||||||
|
WeakReferenceMessenger.Default.Send(new MailAddedMessage(Item, EntityUpdateSource.ClientReverted));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BatchChangeJunkStateRequest : BatchCollection<ChangeJunkStateRequest>
|
||||||
|
{
|
||||||
|
public BatchChangeJunkStateRequest(IEnumerable<ChangeJunkStateRequest> collection) : base(collection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -183,7 +183,10 @@ public class WinoRequestProcessor : IWinoRequestProcessor
|
|||||||
var inboxFolder = await _folderService.GetSpecialFolderByAccountIdAsync(mailItem.AssignedAccount.Id, SpecialFolderType.Inbox)
|
var inboxFolder = await _folderService.GetSpecialFolderByAccountIdAsync(mailItem.AssignedAccount.Id, SpecialFolderType.Inbox)
|
||||||
?? throw new UnavailableSpecialFolderException(SpecialFolderType.Inbox, mailItem.AssignedAccount.Id);
|
?? throw new UnavailableSpecialFolderException(SpecialFolderType.Inbox, mailItem.AssignedAccount.Id);
|
||||||
|
|
||||||
|
if (mailItem.AssignedAccount.ProviderType == MailProviderType.IMAP4)
|
||||||
return new MoveRequest(mailItem, mailItem.AssignedFolder, inboxFolder);
|
return new MoveRequest(mailItem, mailItem.AssignedFolder, inboxFolder);
|
||||||
|
|
||||||
|
return new ChangeJunkStateRequest(false, mailItem, mailItem.AssignedFolder, inboxFolder);
|
||||||
}
|
}
|
||||||
else if (action == MailOperation.UnArchive)
|
else if (action == MailOperation.UnArchive)
|
||||||
{
|
{
|
||||||
@@ -204,7 +207,10 @@ public class WinoRequestProcessor : IWinoRequestProcessor
|
|||||||
var junkFolder = await _folderService.GetSpecialFolderByAccountIdAsync(mailItem.AssignedAccount.Id, SpecialFolderType.Junk)
|
var junkFolder = await _folderService.GetSpecialFolderByAccountIdAsync(mailItem.AssignedAccount.Id, SpecialFolderType.Junk)
|
||||||
?? throw new UnavailableSpecialFolderException(SpecialFolderType.Junk, mailItem.AssignedAccount.Id);
|
?? throw new UnavailableSpecialFolderException(SpecialFolderType.Junk, mailItem.AssignedAccount.Id);
|
||||||
|
|
||||||
|
if (mailItem.AssignedAccount.ProviderType == MailProviderType.IMAP4)
|
||||||
return new MoveRequest(mailItem, mailItem.AssignedFolder, junkFolder);
|
return new MoveRequest(mailItem, mailItem.AssignedFolder, junkFolder);
|
||||||
|
|
||||||
|
return new ChangeJunkStateRequest(true, mailItem, mailItem.AssignedFolder, junkFolder);
|
||||||
}
|
}
|
||||||
else if (action == MailOperation.AlwaysMoveToFocused || action == MailOperation.AlwaysMoveToOther)
|
else if (action == MailOperation.AlwaysMoveToFocused || action == MailOperation.AlwaysMoveToOther)
|
||||||
return new AlwaysMoveToRequest(mailItem, action == MailOperation.AlwaysMoveToFocused);
|
return new AlwaysMoveToRequest(mailItem, action == MailOperation.AlwaysMoveToFocused);
|
||||||
|
|||||||
@@ -1219,6 +1219,36 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
|||||||
return [new HttpRequestBundle<IClientServiceRequest>(networkCall, request)];
|
return [new HttpRequestBundle<IClientServiceRequest>(networkCall, request)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override List<IRequestBundle<IClientServiceRequest>> ChangeJunkState(BatchChangeJunkStateRequest request)
|
||||||
|
{
|
||||||
|
bool isJunk = request[0].IsJunk;
|
||||||
|
|
||||||
|
var addLabelIds = new HashSet<string>();
|
||||||
|
var removeLabelIds = new HashSet<string>();
|
||||||
|
|
||||||
|
if (isJunk)
|
||||||
|
{
|
||||||
|
addLabelIds.Add(ServiceConstants.SPAM_LABEL_ID);
|
||||||
|
removeLabelIds.Add(ServiceConstants.INBOX_LABEL_ID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addLabelIds.Add(ServiceConstants.INBOX_LABEL_ID);
|
||||||
|
removeLabelIds.Add(ServiceConstants.SPAM_LABEL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
var batchModifyRequest = new BatchModifyMessagesRequest
|
||||||
|
{
|
||||||
|
Ids = request.Select(a => a.Item.Id.ToString()).ToList(),
|
||||||
|
AddLabelIds = addLabelIds.ToList(),
|
||||||
|
RemoveLabelIds = removeLabelIds.ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
||||||
|
|
||||||
|
return [new HttpRequestBundle<IClientServiceRequest>(networkCall, request)];
|
||||||
|
}
|
||||||
|
|
||||||
public override List<IRequestBundle<IClientServiceRequest>> MarkRead(BatchMarkReadRequest request)
|
public override List<IRequestBundle<IClientServiceRequest>> MarkRead(BatchMarkReadRequest request)
|
||||||
{
|
{
|
||||||
bool readStatus = request[0].IsRead;
|
bool readStatus = request[0].IsRead;
|
||||||
@@ -1783,11 +1813,13 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
|||||||
private static bool IsExistingEntityOperation(IUIChangeRequest request)
|
private static bool IsExistingEntityOperation(IUIChangeRequest request)
|
||||||
=> request is BatchDeleteRequest
|
=> request is BatchDeleteRequest
|
||||||
|| request is BatchMoveRequest
|
|| request is BatchMoveRequest
|
||||||
|
|| request is BatchChangeJunkStateRequest
|
||||||
|| request is BatchChangeFlagRequest
|
|| request is BatchChangeFlagRequest
|
||||||
|| request is BatchMarkReadRequest
|
|| request is BatchMarkReadRequest
|
||||||
|| request is BatchArchiveRequest
|
|| request is BatchArchiveRequest
|
||||||
|| request is DeleteRequest
|
|| request is DeleteRequest
|
||||||
|| request is MoveRequest
|
|| request is MoveRequest
|
||||||
|
|| request is ChangeJunkStateRequest
|
||||||
|| request is ChangeFlagRequest
|
|| request is ChangeFlagRequest
|
||||||
|| request is MarkReadRequest
|
|| request is MarkReadRequest
|
||||||
|| request is ArchiveRequest
|
|| request is ArchiveRequest
|
||||||
@@ -1803,6 +1835,8 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
|||||||
private static bool ShouldRevertOptimisticMailStateChange(IUIChangeRequest request)
|
private static bool ShouldRevertOptimisticMailStateChange(IUIChangeRequest request)
|
||||||
=> request is BatchMarkReadRequest
|
=> request is BatchMarkReadRequest
|
||||||
|| request is MarkReadRequest
|
|| request is MarkReadRequest
|
||||||
|
|| request is BatchChangeJunkStateRequest
|
||||||
|
|| request is ChangeJunkStateRequest
|
||||||
|| request is BatchChangeFlagRequest
|
|| request is BatchChangeFlagRequest
|
||||||
|| request is ChangeFlagRequest;
|
|| request is ChangeFlagRequest;
|
||||||
|
|
||||||
@@ -2504,25 +2538,28 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
|||||||
googleEvent.Start = new EventDateTime
|
googleEvent.Start = new EventDateTime
|
||||||
{
|
{
|
||||||
Date = calendarItem.StartDate.ToString("yyyy-MM-dd"),
|
Date = calendarItem.StartDate.ToString("yyyy-MM-dd"),
|
||||||
TimeZone = calendarItem.StartTimeZone
|
TimeZone = NormalizeGoogleTimeZoneId(calendarItem.StartTimeZone)
|
||||||
};
|
};
|
||||||
googleEvent.End = new EventDateTime
|
googleEvent.End = new EventDateTime
|
||||||
{
|
{
|
||||||
Date = calendarItem.EndDate.ToString("yyyy-MM-dd"),
|
Date = calendarItem.EndDate.ToString("yyyy-MM-dd"),
|
||||||
TimeZone = calendarItem.EndTimeZone
|
TimeZone = NormalizeGoogleTimeZoneId(calendarItem.EndTimeZone)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
var startTimeZone = NormalizeGoogleTimeZoneId(calendarItem.StartTimeZone);
|
||||||
|
var endTimeZone = NormalizeGoogleTimeZoneId(calendarItem.EndTimeZone ?? calendarItem.StartTimeZone);
|
||||||
|
|
||||||
googleEvent.Start = new EventDateTime
|
googleEvent.Start = new EventDateTime
|
||||||
{
|
{
|
||||||
DateTimeDateTimeOffset = new DateTimeOffset(calendarItem.StartDate, ResolveOffset(calendarItem.StartDate, calendarItem.StartTimeZone)),
|
DateTimeDateTimeOffset = new DateTimeOffset(calendarItem.StartDate, ResolveOffset(calendarItem.StartDate, calendarItem.StartTimeZone)),
|
||||||
TimeZone = calendarItem.StartTimeZone
|
TimeZone = startTimeZone
|
||||||
};
|
};
|
||||||
googleEvent.End = new EventDateTime
|
googleEvent.End = new EventDateTime
|
||||||
{
|
{
|
||||||
DateTimeDateTimeOffset = new DateTimeOffset(calendarItem.EndDate, ResolveOffset(calendarItem.EndDate, calendarItem.EndTimeZone ?? calendarItem.StartTimeZone)),
|
DateTimeDateTimeOffset = new DateTimeOffset(calendarItem.EndDate, ResolveOffset(calendarItem.EndDate, calendarItem.EndTimeZone ?? calendarItem.StartTimeZone)),
|
||||||
TimeZone = calendarItem.EndTimeZone
|
TimeZone = endTimeZone
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2896,4 +2933,18 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
|||||||
return TimeSpan.Zero;
|
return TimeSpan.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string NormalizeGoogleTimeZoneId(string timeZoneId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(timeZoneId))
|
||||||
|
return timeZoneId;
|
||||||
|
|
||||||
|
if (timeZoneId.Contains('/'))
|
||||||
|
return timeZoneId;
|
||||||
|
|
||||||
|
if (TimeZoneInfo.TryConvertWindowsIdToIanaId(timeZoneId, out var ianaTimeZoneId))
|
||||||
|
return ianaTimeZoneId;
|
||||||
|
|
||||||
|
return timeZoneId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1358,12 +1358,10 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
/// <param name="requestInformation">Post request information.</param>
|
/// <param name="requestInformation">Post request information.</param>
|
||||||
/// <param name="content">Content object to serialize.</param>
|
/// <param name="content">Content object to serialize.</param>
|
||||||
/// <returns>Updated post request information.</returns>
|
/// <returns>Updated post request information.</returns>
|
||||||
private RequestInformation PreparePostRequestInformation(RequestInformation requestInformation, Microsoft.Graph.Me.Messages.Item.Move.MovePostRequestBody content = null)
|
private RequestInformation PreparePostRequestInformation(RequestInformation requestInformation, string contentJson = "{}")
|
||||||
{
|
{
|
||||||
requestInformation.Headers.Clear();
|
requestInformation.Headers.Clear();
|
||||||
|
|
||||||
string contentJson = content == null ? "{}" : JsonSerializer.Serialize(content, OutlookSynchronizerJsonContext.Default.MovePostRequestBody);
|
|
||||||
|
|
||||||
requestInformation.Content = new MemoryStream(Encoding.UTF8.GetBytes(contentJson));
|
requestInformation.Content = new MemoryStream(Encoding.UTF8.GetBytes(contentJson));
|
||||||
requestInformation.HttpMethod = Method.POST;
|
requestInformation.HttpMethod = Method.POST;
|
||||||
requestInformation.Headers.Add("Content-Type", "application/json");
|
requestInformation.Headers.Add("Content-Type", "application/json");
|
||||||
@@ -1371,6 +1369,26 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
return requestInformation;
|
return requestInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RequestInformation PreparePostRequestInformation(RequestInformation requestInformation, Microsoft.Graph.Me.Messages.Item.Move.MovePostRequestBody content)
|
||||||
|
=> PreparePostRequestInformation(requestInformation, JsonSerializer.Serialize(content, OutlookSynchronizerJsonContext.Default.MovePostRequestBody));
|
||||||
|
|
||||||
|
private RequestInformation PrepareReportMessageRequestInformation(ChangeJunkStateRequest request)
|
||||||
|
{
|
||||||
|
var reportAction = request.IsJunk ? "junk" : "notJunk";
|
||||||
|
var body = $$"""
|
||||||
|
{
|
||||||
|
"IsMessageMoveRequested": true,
|
||||||
|
"ReportAction": "{{reportAction}}"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
return PreparePostRequestInformation(new RequestInformation
|
||||||
|
{
|
||||||
|
URI = new Uri($"https://graph.microsoft.com/beta/me/messages/{Uri.EscapeDataString(request.Item.Id)}/reportMessage"),
|
||||||
|
HttpMethod = Method.POST
|
||||||
|
}, body);
|
||||||
|
}
|
||||||
|
|
||||||
#region Mail Integration
|
#region Mail Integration
|
||||||
|
|
||||||
public override bool DelaySendOperationSynchronization() => true;
|
public override bool DelaySendOperationSynchronization() => true;
|
||||||
@@ -1402,6 +1420,16 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override List<IRequestBundle<RequestInformation>> ChangeJunkState(BatchChangeJunkStateRequest request)
|
||||||
|
{
|
||||||
|
return request
|
||||||
|
.Select(item => (IRequestBundle<RequestInformation>)new HttpRequestBundle<RequestInformation>(
|
||||||
|
PrepareReportMessageRequestInformation(item),
|
||||||
|
item,
|
||||||
|
item))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public override List<IRequestBundle<RequestInformation>> MarkRead(BatchMarkReadRequest request)
|
public override List<IRequestBundle<RequestInformation>> MarkRead(BatchMarkReadRequest request)
|
||||||
{
|
{
|
||||||
return ForEachRequest(request, (item) =>
|
return ForEachRequest(request, (item) =>
|
||||||
@@ -1747,8 +1775,32 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var directRequests = batchedRequests
|
||||||
|
.Where(bundle => bundle.Request is ChangeJunkStateRequest)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var directRequest in directRequests)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _graphClient.RequestAdapter.SendAsync(
|
||||||
|
directRequest.NativeRequest,
|
||||||
|
Message.CreateFromDiscriminatorValue,
|
||||||
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
directRequest.UIChangeRequest?.RevertUIChanges();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now batch and execute the network requests.
|
// Now batch and execute the network requests.
|
||||||
var batchedGroups = batchedRequests.Batch((int)MaximumAllowedBatchRequestSize);
|
var batchEligibleRequests = batchedRequests
|
||||||
|
.Except(directRequests)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var batchedGroups = batchEligibleRequests.Batch((int)MaximumAllowedBatchRequestSize);
|
||||||
|
|
||||||
foreach (var batch in batchedGroups)
|
foreach (var batch in batchedGroups)
|
||||||
{
|
{
|
||||||
@@ -1910,11 +1962,13 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
|||||||
private static bool IsExistingEntityOperation(IUIChangeRequest request)
|
private static bool IsExistingEntityOperation(IUIChangeRequest request)
|
||||||
=> request is BatchDeleteRequest
|
=> request is BatchDeleteRequest
|
||||||
|| request is BatchMoveRequest
|
|| request is BatchMoveRequest
|
||||||
|
|| request is BatchChangeJunkStateRequest
|
||||||
|| request is BatchChangeFlagRequest
|
|| request is BatchChangeFlagRequest
|
||||||
|| request is BatchMarkReadRequest
|
|| request is BatchMarkReadRequest
|
||||||
|| request is BatchArchiveRequest
|
|| request is BatchArchiveRequest
|
||||||
|| request is DeleteRequest
|
|| request is DeleteRequest
|
||||||
|| request is MoveRequest
|
|| request is MoveRequest
|
||||||
|
|| request is ChangeJunkStateRequest
|
||||||
|| request is ChangeFlagRequest
|
|| request is ChangeFlagRequest
|
||||||
|| request is MarkReadRequest
|
|| request is MarkReadRequest
|
||||||
|| request is ArchiveRequest
|
|| request is ArchiveRequest
|
||||||
|
|||||||
@@ -181,6 +181,9 @@ public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEven
|
|||||||
case MailSynchronizerOperation.ChangeFlag:
|
case MailSynchronizerOperation.ChangeFlag:
|
||||||
nativeRequests.AddRange(ChangeFlag(new BatchChangeFlagRequest(group.Cast<ChangeFlagRequest>())));
|
nativeRequests.AddRange(ChangeFlag(new BatchChangeFlagRequest(group.Cast<ChangeFlagRequest>())));
|
||||||
break;
|
break;
|
||||||
|
case MailSynchronizerOperation.ChangeJunkState:
|
||||||
|
nativeRequests.AddRange(ChangeJunkState(new BatchChangeJunkStateRequest(group.Cast<ChangeJunkStateRequest>())));
|
||||||
|
break;
|
||||||
case MailSynchronizerOperation.AlwaysMoveTo:
|
case MailSynchronizerOperation.AlwaysMoveTo:
|
||||||
nativeRequests.AddRange(AlwaysMoveTo(new BatchAlwaysMoveToRequest(group.Cast<AlwaysMoveToRequest>())));
|
nativeRequests.AddRange(AlwaysMoveTo(new BatchAlwaysMoveToRequest(group.Cast<AlwaysMoveToRequest>())));
|
||||||
break;
|
break;
|
||||||
@@ -577,6 +580,7 @@ public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEven
|
|||||||
public virtual bool DelaySendOperationSynchronization() => false;
|
public virtual bool DelaySendOperationSynchronization() => false;
|
||||||
public virtual List<IRequestBundle<TBaseRequest>> Move(BatchMoveRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
public virtual List<IRequestBundle<TBaseRequest>> Move(BatchMoveRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||||
public virtual List<IRequestBundle<TBaseRequest>> ChangeFlag(BatchChangeFlagRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
public virtual List<IRequestBundle<TBaseRequest>> ChangeFlag(BatchChangeFlagRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||||
|
public virtual List<IRequestBundle<TBaseRequest>> ChangeJunkState(BatchChangeJunkStateRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||||
public virtual List<IRequestBundle<TBaseRequest>> MarkRead(BatchMarkReadRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
public virtual List<IRequestBundle<TBaseRequest>> MarkRead(BatchMarkReadRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||||
public virtual List<IRequestBundle<TBaseRequest>> Delete(BatchDeleteRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
public virtual List<IRequestBundle<TBaseRequest>> Delete(BatchDeleteRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||||
public virtual List<IRequestBundle<TBaseRequest>> AlwaysMoveTo(BatchAlwaysMoveToRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
public virtual List<IRequestBundle<TBaseRequest>> AlwaysMoveTo(BatchAlwaysMoveToRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||||
|
|||||||
@@ -637,6 +637,12 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
|||||||
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MarkAsUnread, true, false));
|
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MarkAsUnread, true, false));
|
||||||
else
|
else
|
||||||
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MarkAsRead, true, false));
|
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MarkAsRead, true, false));
|
||||||
|
|
||||||
|
if (initializedMailItemViewModel.MailCopy.AssignedFolder.SpecialFolderType == SpecialFolderType.Junk)
|
||||||
|
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MarkAsNotJunk, true, true));
|
||||||
|
else if (!initializedMailItemViewModel.IsDraft &&
|
||||||
|
initializedMailItemViewModel.MailCopy.AssignedFolder.SpecialFolderType != SpecialFolderType.Sent)
|
||||||
|
MenuItems.Add(MailOperationMenuItem.Create(MailOperation.MoveToJunk, true, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnMailUpdated(MailCopy updatedMail, EntityUpdateSource source, MailCopyChangeFlags changedProperties)
|
protected override async void OnMailUpdated(MailCopy updatedMail, EntityUpdateSource source, MailCopyChangeFlags changedProperties)
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ public static class XamlHelpers
|
|||||||
MailOperation.SoftDelete => Translator.MailOperation_Delete,
|
MailOperation.SoftDelete => Translator.MailOperation_Delete,
|
||||||
MailOperation.HardDelete => Translator.MailOperation_Delete,
|
MailOperation.HardDelete => Translator.MailOperation_Delete,
|
||||||
MailOperation.Move => Translator.MailOperation_Move,
|
MailOperation.Move => Translator.MailOperation_Move,
|
||||||
MailOperation.MoveToJunk => Translator.MailOperation_MoveJunk,
|
MailOperation.MoveToJunk => Translator.MailOperation_MarkAsJunk,
|
||||||
MailOperation.MoveToFocused => Translator.MailOperation_MoveFocused,
|
MailOperation.MoveToFocused => Translator.MailOperation_MoveFocused,
|
||||||
MailOperation.MoveToOther => Translator.MailOperation_MoveOther,
|
MailOperation.MoveToOther => Translator.MailOperation_MoveOther,
|
||||||
MailOperation.AlwaysMoveToOther => Translator.MailOperation_AlwaysMoveOther,
|
MailOperation.AlwaysMoveToOther => Translator.MailOperation_AlwaysMoveOther,
|
||||||
|
|||||||
@@ -383,6 +383,12 @@ public class PreferencesService(IConfigurationService configurationService) : Ob
|
|||||||
set => SetPropertyAndSave(nameof(IsWinoAccountButtonHidden), value);
|
set => SetPropertyAndSave(nameof(IsWinoAccountButtonHidden), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsAiActionsPanelHidden
|
||||||
|
{
|
||||||
|
get => _configurationService.Get(nameof(IsAiActionsPanelHidden), false);
|
||||||
|
set => SetPropertyAndSave(nameof(IsAiActionsPanelHidden), value);
|
||||||
|
}
|
||||||
|
|
||||||
public string AiDefaultTranslationLanguageCode
|
public string AiDefaultTranslationLanguageCode
|
||||||
{
|
{
|
||||||
get => _configurationService.Get(nameof(AiDefaultTranslationLanguageCode), "en-US");
|
get => _configurationService.Get(nameof(AiDefaultTranslationLanguageCode), "en-US");
|
||||||
|
|||||||
@@ -166,6 +166,7 @@
|
|||||||
MinWidth="40"
|
MinWidth="40"
|
||||||
HorizontalContentAlignment="Center"
|
HorizontalContentAlignment="Center"
|
||||||
LabelPosition="Collapsed"
|
LabelPosition="Collapsed"
|
||||||
|
Visibility="{x:Bind GetAiActionsToggleVisibility(ViewModel.PreferencesService.IsAiActionsPanelHidden), Mode=OneWay}"
|
||||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_AiActions}">
|
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_AiActions}">
|
||||||
<AppBarToggleButton.Icon>
|
<AppBarToggleButton.Icon>
|
||||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||||
@@ -464,7 +465,7 @@
|
|||||||
Margin="0,8,0,0"
|
Margin="0,8,0,0"
|
||||||
AvailableActions="Rewrite"
|
AvailableActions="Rewrite"
|
||||||
HtmlHost="{x:Bind}"
|
HtmlHost="{x:Bind}"
|
||||||
Visibility="{x:Bind GetAiActionsPanelVisibility(ComposeAiActionsToggleButton.IsChecked), Mode=OneWay}" />
|
Visibility="{x:Bind GetAiActionsPanelVisibility(ComposeAiActionsToggleButton.IsChecked, ViewModel.PreferencesService.IsAiActionsPanelHidden), Mode=OneWay}" />
|
||||||
|
|
||||||
<!-- Attachments -->
|
<!-- Attachments -->
|
||||||
<ListView
|
<ListView
|
||||||
|
|||||||
@@ -39,7 +39,10 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
|||||||
{
|
{
|
||||||
public WebView2 GetWebView() => WebViewEditor.GetUnderlyingWebView();
|
public WebView2 GetWebView() => WebViewEditor.GetUnderlyingWebView();
|
||||||
|
|
||||||
public Visibility GetAiActionsPanelVisibility(bool? isChecked) => isChecked == true ? Visibility.Visible : Visibility.Collapsed;
|
public Visibility GetAiActionsToggleVisibility(bool isHidden) => isHidden ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
|
||||||
|
public Visibility GetAiActionsPanelVisibility(bool? isChecked, bool isHidden)
|
||||||
|
=> !isHidden && isChecked == true ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
private readonly List<IDisposable> _disposables = [];
|
private readonly List<IDisposable> _disposables = [];
|
||||||
|
|
||||||
|
|||||||
@@ -269,7 +269,7 @@
|
|||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
DefaultLabelPosition="Right"
|
DefaultLabelPosition="Right"
|
||||||
IsAIActionsPaneToggleVisible="True"
|
IsAIActionsPaneToggleVisible="{x:Bind GetAiActionsToggleVisible(ViewModel.PreferencesService.IsAiActionsPanelHidden), Mode=OneWay}"
|
||||||
IsEditorThemeDark="{x:Bind ViewModel.IsDarkWebviewRenderer, Mode=TwoWay}"
|
IsEditorThemeDark="{x:Bind ViewModel.IsDarkWebviewRenderer, Mode=TwoWay}"
|
||||||
IsEditorThemeToggleVisible="True"
|
IsEditorThemeToggleVisible="True"
|
||||||
ItemInvokedCommand="{x:Bind ViewModel.OperationClickedCommand}"
|
ItemInvokedCommand="{x:Bind ViewModel.OperationClickedCommand}"
|
||||||
@@ -415,7 +415,7 @@
|
|||||||
Margin="0,8,0,0"
|
Margin="0,8,0,0"
|
||||||
AvailableActions="Translate, Summarize"
|
AvailableActions="Translate, Summarize"
|
||||||
HtmlHost="{x:Bind}"
|
HtmlHost="{x:Bind}"
|
||||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(RendererCommandBar.IsAIActionsEnabled), Mode=OneWay}" />
|
Visibility="{x:Bind GetAiActionsPanelVisibility(RendererCommandBar.IsAIActionsEnabled, ViewModel.PreferencesService.IsAiActionsPanelHidden), Mode=OneWay}" />
|
||||||
|
|
||||||
<!-- Attachments -->
|
<!-- Attachments -->
|
||||||
<Grid Grid.Row="4">
|
<Grid Grid.Row="4">
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
|||||||
private string _currentRenderedHtml = string.Empty;
|
private string _currentRenderedHtml = string.Empty;
|
||||||
|
|
||||||
public WebView2 GetWebView() => Chromium;
|
public WebView2 GetWebView() => Chromium;
|
||||||
|
public bool GetAiActionsToggleVisible(bool isHidden) => !isHidden;
|
||||||
|
public Visibility GetAiActionsPanelVisibility(bool isEnabled, bool isHidden)
|
||||||
|
=> !isHidden && isEnabled ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
public MailRenderingPage()
|
public MailRenderingPage()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,12 +62,7 @@
|
|||||||
<PathIcon Data="F1 M 0 9.375 C 0 8.509115 0.110677 7.677409 0.332031 6.879883 C 0.553385 6.082357 0.867513 5.335287 1.274414 4.638672 C 1.681315 3.942059 2.169596 3.30892 2.739258 2.739258 C 3.308919 2.169598 3.942057 1.681316 4.638672 1.274414 C 5.335286 0.867514 6.082356 0.553387 6.879883 0.332031 C 7.677409 0.110678 8.509114 0 9.375 0 C 10.234375 0 11.062825 0.112305 11.860352 0.336914 C 12.657877 0.561523 13.404947 0.877279 14.101562 1.28418 C 14.798176 1.691082 15.431314 2.179363 16.000977 2.749023 C 16.570637 3.318686 17.058918 3.951824 17.46582 4.648438 C 17.872721 5.345053 18.188477 6.092123 18.413086 6.889648 C 18.637695 7.687175 18.75 8.515625 18.75 9.375 C 18.75 10.240886 18.637695 11.072592 18.413086 11.870117 C 18.188477 12.667644 17.872721 13.413086 17.46582 14.106445 C 17.058918 14.799805 16.570637 15.431315 16.000977 16.000977 C 15.431314 16.570639 14.799804 17.05892 14.106445 17.46582 C 13.413085 17.872721 12.666015 18.188477 11.865234 18.413086 C 11.064453 18.637695 10.234375 18.75 9.375 18.75 C 8.509114 18.75 7.675781 18.639322 6.875 18.417969 C 6.074219 18.196615 5.327148 17.882486 4.633789 17.475586 C 3.94043 17.068686 3.308919 16.580404 2.739258 16.010742 C 2.169596 15.441081 1.681315 14.80957 1.274414 14.116211 C 0.867513 13.422852 0.553385 12.675781 0.332031 11.875 C 0.110677 11.074219 0 10.240886 0 9.375 Z M 17.5 9.375 C 17.5 8.626303 17.403971 7.905273 17.211914 7.211914 C 17.019855 6.518556 16.746418 5.87077 16.391602 5.268555 C 16.036783 4.666342 15.613606 4.119467 15.12207 3.62793 C 14.630533 3.136395 14.083658 2.713217 13.481445 2.358398 C 12.879231 2.003582 12.231445 1.730145 11.538086 1.538086 C 10.844727 1.346029 10.123697 1.25 9.375 1.25 C 8.626302 1.25 7.905273 1.346029 7.211914 1.538086 C 6.518555 1.730145 5.870768 2.003582 5.268555 2.358398 C 4.666341 2.713217 4.119466 3.136395 3.62793 3.62793 C 3.136393 4.119467 2.713216 4.666342 2.358398 5.268555 C 2.003581 5.87077 1.730143 6.518556 1.538086 7.211914 C 1.346029 7.905273 1.25 8.626303 1.25 9.375 C 1.25 10.123698 1.346029 10.844727 1.538086 11.538086 C 1.730143 12.231445 2.001953 12.879232 2.353516 13.481445 C 2.705078 14.083659 3.128255 14.632162 3.623047 15.126953 C 4.117838 15.621745 4.666341 16.044922 5.268555 16.396484 C 5.870768 16.748047 6.518555 17.019857 7.211914 17.211914 C 7.905273 17.403971 8.626302 17.5 9.375 17.5 C 10.123697 17.5 10.844727 17.403971 11.538086 17.211914 C 12.231445 17.019857 12.879231 16.748047 13.481445 16.396484 C 14.083658 16.044922 14.63216 15.621745 15.126953 15.126953 C 15.621744 14.632162 16.044922 14.083659 16.396484 13.481445 C 16.748047 12.879232 17.019855 12.231445 17.211914 11.538086 C 17.403971 10.844727 17.5 10.123698 17.5 9.375 Z M 9.375 10 C 9.205729 10 9.059244 9.938151 8.935547 9.814453 C 8.811849 9.690756 8.75 9.544271 8.75 9.375 L 8.75 4.375 C 8.75 4.20573 8.811849 4.059246 8.935547 3.935547 C 9.059244 3.81185 9.205729 3.75 9.375 3.75 C 9.544271 3.75 9.690755 3.81185 9.814453 3.935547 C 9.93815 4.059246 10 4.20573 10 4.375 L 10 8.75 L 13.125 8.75 C 13.294271 8.75 13.440755 8.81185 13.564453 8.935547 C 13.68815 9.059245 13.75 9.205729 13.75 9.375 C 13.75 9.544271 13.68815 9.690756 13.564453 9.814453 C 13.440755 9.938151 13.294271 10 13.125 10 Z " />
|
<PathIcon Data="F1 M 0 9.375 C 0 8.509115 0.110677 7.677409 0.332031 6.879883 C 0.553385 6.082357 0.867513 5.335287 1.274414 4.638672 C 1.681315 3.942059 2.169596 3.30892 2.739258 2.739258 C 3.308919 2.169598 3.942057 1.681316 4.638672 1.274414 C 5.335286 0.867514 6.082356 0.553387 6.879883 0.332031 C 7.677409 0.110678 8.509114 0 9.375 0 C 10.234375 0 11.062825 0.112305 11.860352 0.336914 C 12.657877 0.561523 13.404947 0.877279 14.101562 1.28418 C 14.798176 1.691082 15.431314 2.179363 16.000977 2.749023 C 16.570637 3.318686 17.058918 3.951824 17.46582 4.648438 C 17.872721 5.345053 18.188477 6.092123 18.413086 6.889648 C 18.637695 7.687175 18.75 8.515625 18.75 9.375 C 18.75 10.240886 18.637695 11.072592 18.413086 11.870117 C 18.188477 12.667644 17.872721 13.413086 17.46582 14.106445 C 17.058918 14.799805 16.570637 15.431315 16.000977 16.000977 C 15.431314 16.570639 14.799804 17.05892 14.106445 17.46582 C 13.413085 17.872721 12.666015 18.188477 11.865234 18.413086 C 11.064453 18.637695 10.234375 18.75 9.375 18.75 C 8.509114 18.75 7.675781 18.639322 6.875 18.417969 C 6.074219 18.196615 5.327148 17.882486 4.633789 17.475586 C 3.94043 17.068686 3.308919 16.580404 2.739258 16.010742 C 2.169596 15.441081 1.681315 14.80957 1.274414 14.116211 C 0.867513 13.422852 0.553385 12.675781 0.332031 11.875 C 0.110677 11.074219 0 10.240886 0 9.375 Z M 17.5 9.375 C 17.5 8.626303 17.403971 7.905273 17.211914 7.211914 C 17.019855 6.518556 16.746418 5.87077 16.391602 5.268555 C 16.036783 4.666342 15.613606 4.119467 15.12207 3.62793 C 14.630533 3.136395 14.083658 2.713217 13.481445 2.358398 C 12.879231 2.003582 12.231445 1.730145 11.538086 1.538086 C 10.844727 1.346029 10.123697 1.25 9.375 1.25 C 8.626302 1.25 7.905273 1.346029 7.211914 1.538086 C 6.518555 1.730145 5.870768 2.003582 5.268555 2.358398 C 4.666341 2.713217 4.119466 3.136395 3.62793 3.62793 C 3.136393 4.119467 2.713216 4.666342 2.358398 5.268555 C 2.003581 5.87077 1.730143 6.518556 1.538086 7.211914 C 1.346029 7.905273 1.25 8.626303 1.25 9.375 C 1.25 10.123698 1.346029 10.844727 1.538086 11.538086 C 1.730143 12.231445 2.001953 12.879232 2.353516 13.481445 C 2.705078 14.083659 3.128255 14.632162 3.623047 15.126953 C 4.117838 15.621745 4.666341 16.044922 5.268555 16.396484 C 5.870768 16.748047 6.518555 17.019857 7.211914 17.211914 C 7.905273 17.403971 8.626302 17.5 9.375 17.5 C 10.123697 17.5 10.844727 17.403971 11.538086 17.211914 C 12.231445 17.019857 12.879231 16.748047 13.481445 16.396484 C 14.083658 16.044922 14.63216 15.621745 15.126953 15.126953 C 15.621744 14.632162 16.044922 14.083659 16.396484 13.481445 C 16.748047 12.879232 17.019855 12.231445 17.211914 11.538086 C 17.403971 10.844727 17.5 10.123698 17.5 9.375 Z M 9.375 10 C 9.205729 10 9.059244 9.938151 8.935547 9.814453 C 8.811849 9.690756 8.75 9.544271 8.75 9.375 L 8.75 4.375 C 8.75 4.20573 8.811849 4.059246 8.935547 3.935547 C 9.059244 3.81185 9.205729 3.75 9.375 3.75 C 9.544271 3.75 9.690755 3.81185 9.814453 3.935547 C 9.93815 4.059246 10 4.20573 10 4.375 L 10 8.75 L 13.125 8.75 C 13.294271 8.75 13.440755 8.81185 13.564453 8.935547 C 13.68815 9.059245 13.75 9.205729 13.75 9.375 C 13.75 9.544271 13.68815 9.690756 13.564453 9.814453 C 13.440755 9.938151 13.294271 10 13.125 10 Z " />
|
||||||
</controls:SettingsCard.HeaderIcon>
|
</controls:SettingsCard.HeaderIcon>
|
||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_HideWinoAccountButton_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_HideWinoAccountButton_Title}">
|
|
||||||
<ToggleSwitch IsOn="{x:Bind ViewModel.PreferencesService.IsWinoAccountButtonHidden, Mode=TwoWay}" />
|
|
||||||
<controls:SettingsCard.HeaderIcon>
|
|
||||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
|
||||||
</controls:SettingsCard.HeaderIcon>
|
|
||||||
</controls:SettingsCard>
|
|
||||||
|
|
||||||
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_StoreUpdateNotifications_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_StoreUpdateNotifications_Title}">
|
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_StoreUpdateNotifications_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_StoreUpdateNotifications_Title}">
|
||||||
<ToggleSwitch IsOn="{x:Bind ViewModel.PreferencesService.IsStoreUpdateNotificationsEnabled, Mode=TwoWay}" />
|
<ToggleSwitch IsOn="{x:Bind ViewModel.PreferencesService.IsStoreUpdateNotificationsEnabled, Mode=TwoWay}" />
|
||||||
@@ -105,11 +100,11 @@
|
|||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
|
|
||||||
<controls:SettingsCard
|
<controls:SettingsCard
|
||||||
Description="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Description}"
|
|
||||||
Header="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Title}"
|
|
||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
VerticalContentAlignment="Stretch"
|
VerticalContentAlignment="Stretch"
|
||||||
ContentAlignment="Vertical">
|
ContentAlignment="Vertical"
|
||||||
|
Description="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Description}"
|
||||||
|
Header="{x:Bind domain:Translator.SettingsAppPreferences_AiSummarySavePath_Title}">
|
||||||
<StackPanel Spacing="8">
|
<StackPanel Spacing="8">
|
||||||
<Grid ColumnSpacing="12">
|
<Grid ColumnSpacing="12">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -134,6 +129,20 @@
|
|||||||
Visibility="{x:Bind ViewModel.HasInvalidSummarySavePath, Mode=OneWay}" />
|
Visibility="{x:Bind ViewModel.HasInvalidSummarySavePath, Mode=OneWay}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_HideWinoAccountButton_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_HideWinoAccountButton_Title}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.PreferencesService.IsWinoAccountButtonHidden, Mode=TwoWay}" />
|
||||||
|
<!--<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>-->
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_HideAiActionsPanel_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_HideAiActionsPanel_Title}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.PreferencesService.IsAiActionsPanelHidden, Mode=TwoWay}" />
|
||||||
|
<!--<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>-->
|
||||||
|
</controls:SettingsCard>
|
||||||
</controls:SettingsExpander.Items>
|
</controls:SettingsExpander.Items>
|
||||||
</controls:SettingsExpander>
|
</controls:SettingsExpander>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -175,6 +175,11 @@ public class ContextMenuItemService : IContextMenuItemService
|
|||||||
else
|
else
|
||||||
actionList.Add(MailOperationMenuItem.Create(MailOperation.MarkAsRead, true, false));
|
actionList.Add(MailOperationMenuItem.Create(MailOperation.MarkAsRead, true, false));
|
||||||
|
|
||||||
|
if (mailItem.AssignedFolder.SpecialFolderType == SpecialFolderType.Junk)
|
||||||
|
actionList.Add(MailOperationMenuItem.Create(MailOperation.MarkAsNotJunk, true, true));
|
||||||
|
else if (!mailItem.IsDraft && mailItem.AssignedFolder.SpecialFolderType != SpecialFolderType.Sent)
|
||||||
|
actionList.Add(MailOperationMenuItem.Create(MailOperation.MoveToJunk, true, true));
|
||||||
|
|
||||||
return actionList;
|
return actionList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user