Merge branch 'main' into hotfix/Expander
This commit is contained in:
@@ -1,11 +0,0 @@
|
|||||||
namespace Wino.Core.Domain.Enums
|
|
||||||
{
|
|
||||||
public enum EditorToolbarSectionType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Format,
|
|
||||||
Insert,
|
|
||||||
Draw,
|
|
||||||
Options
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Wino.Core.Domain.Enums
|
|
||||||
{
|
|
||||||
public enum MenuPaneMode
|
|
||||||
{
|
|
||||||
Visible,
|
|
||||||
Hidden
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ namespace Wino.Core.Domain.Interfaces
|
|||||||
public interface IThemeService : IInitializeAsync
|
public interface IThemeService : IInitializeAsync
|
||||||
{
|
{
|
||||||
event EventHandler<ApplicationElementTheme> ElementThemeChanged;
|
event EventHandler<ApplicationElementTheme> ElementThemeChanged;
|
||||||
event EventHandler<string> AccentColorChangedBySystem;
|
|
||||||
event EventHandler<string> AccentColorChanged;
|
event EventHandler<string> AccentColorChanged;
|
||||||
|
|
||||||
Task<List<AppThemeBase>> GetAvailableThemesAsync();
|
Task<List<AppThemeBase>> GetAvailableThemesAsync();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
|
|
||||||
namespace Wino.Core.Domain.Interfaces
|
namespace Wino.Core.Domain.Interfaces
|
||||||
@@ -12,7 +13,7 @@ namespace Wino.Core.Domain.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="items">Original mails.</param>
|
/// <param name="items">Original mails.</param>
|
||||||
/// <returns>Original mails with thread mails.</returns>
|
/// <returns>Original mails with thread mails.</returns>
|
||||||
Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items);
|
Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items, IMailItemFolder threadingForFolder);
|
||||||
bool ShouldThreadWithItem(IMailItem originalItem, IMailItem targetItem);
|
bool ShouldThreadWithItem(IMailItem originalItem, IMailItem targetItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,19 +14,19 @@ namespace Wino.Core.Domain.Models.MailItem
|
|||||||
public IMailItem LatestMailItem => ThreadItems.LastOrDefault();
|
public IMailItem LatestMailItem => ThreadItems.LastOrDefault();
|
||||||
public IMailItem FirstMailItem => ThreadItems.FirstOrDefault();
|
public IMailItem FirstMailItem => ThreadItems.FirstOrDefault();
|
||||||
|
|
||||||
public void AddThreadItem(IMailItem item)
|
public bool AddThreadItem(IMailItem item)
|
||||||
{
|
{
|
||||||
if (item == null) return;
|
if (item == null) return false;
|
||||||
|
|
||||||
if (ThreadItems.Any(a => a.Id == item.Id))
|
if (ThreadItems.Any(a => a.Id == item.Id))
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item != null && item.IsDraft)
|
if (item != null && item.IsDraft)
|
||||||
{
|
{
|
||||||
ThreadItems.Insert(0, item);
|
ThreadItems.Insert(0, item);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var insertItem = ThreadItems.FirstOrDefault(a => !a.IsDraft && a.CreationDate < item.CreationDate);
|
var insertItem = ThreadItems.FirstOrDefault(a => !a.IsDraft && a.CreationDate < item.CreationDate);
|
||||||
@@ -39,6 +39,8 @@ namespace Wino.Core.Domain.Models.MailItem
|
|||||||
|
|
||||||
ThreadItems.Insert(index, item);
|
ThreadItems.Insert(index, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Guid> GetContainingIds() => ThreadItems?.Select(a => a.UniqueId) ?? default;
|
public IEnumerable<Guid> GetContainingIds() => ThreadItems?.Select(a => a.UniqueId) ?? default;
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
using Wino.Core.Domain.Enums;
|
|
||||||
|
|
||||||
namespace Wino.Core.Domain.Models.Reader
|
|
||||||
{
|
|
||||||
public class EditorToolbarSection
|
|
||||||
{
|
|
||||||
public EditorToolbarSectionType SectionType { get; set; }
|
|
||||||
public string Title
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (SectionType)
|
|
||||||
{
|
|
||||||
case EditorToolbarSectionType.None:
|
|
||||||
return Translator.EditorToolbarOption_None;
|
|
||||||
case EditorToolbarSectionType.Format:
|
|
||||||
return Translator.EditorToolbarOption_Format;
|
|
||||||
case EditorToolbarSectionType.Insert:
|
|
||||||
return Translator.EditorToolbarOption_Insert;
|
|
||||||
case EditorToolbarSectionType.Draw:
|
|
||||||
return Translator.EditorToolbarOption_Draw;
|
|
||||||
case EditorToolbarSectionType.Options:
|
|
||||||
return Translator.EditorToolbarOption_Options;
|
|
||||||
default:
|
|
||||||
return "Unknown Editor Option";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
"Buttons_TryAgain": "Try Again",
|
"Buttons_TryAgain": "Try Again",
|
||||||
"Buttons_Yes": "Yes",
|
"Buttons_Yes": "Yes",
|
||||||
"Buttons_Reset": "Reset",
|
"Buttons_Reset": "Reset",
|
||||||
|
"Buttons_Send": "Send",
|
||||||
"Center": "Center",
|
"Center": "Center",
|
||||||
"ComingSoon": "Coming soon...",
|
"ComingSoon": "Coming soon...",
|
||||||
"ComposerFrom": "From: ",
|
"ComposerFrom": "From: ",
|
||||||
|
|||||||
5
Wino.Core.Domain/Translator.Designer.cs
generated
5
Wino.Core.Domain/Translator.Designer.cs
generated
@@ -288,6 +288,11 @@ namespace Wino.Core.Domain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Buttons_Reset => Resources.GetTranslatedString(@"Buttons_Reset");
|
public static string Buttons_Reset => Resources.GetTranslatedString(@"Buttons_Reset");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send
|
||||||
|
/// </summary>
|
||||||
|
public static string Buttons_Send => Resources.GetTranslatedString(@"Buttons_Send");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Center
|
/// Center
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MimeKit" Version="4.7.1" />
|
<PackageReference Include="MimeKit" Version="4.7.1" />
|
||||||
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
||||||
<PackageReference Include="sqlite-net-pcl" Version="1.8.116" />
|
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageReference Include="System.Text.Json" Version="8.0.4" />
|
<PackageReference Include="System.Text.Json" Version="8.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ namespace Wino.Services
|
|||||||
|
|
||||||
public event EventHandler<ApplicationElementTheme> ElementThemeChanged;
|
public event EventHandler<ApplicationElementTheme> ElementThemeChanged;
|
||||||
public event EventHandler<string> AccentColorChanged;
|
public event EventHandler<string> AccentColorChanged;
|
||||||
public event EventHandler<string> AccentColorChangedBySystem;
|
|
||||||
|
|
||||||
private const string AccentColorKey = nameof(AccentColorKey);
|
private const string AccentColorKey = nameof(AccentColorKey);
|
||||||
private const string CurrentApplicationThemeKey = nameof(CurrentApplicationThemeKey);
|
private const string CurrentApplicationThemeKey = nameof(CurrentApplicationThemeKey);
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
<Version>7.1.2</Version>
|
<Version>7.1.2</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AppCenter.Analytics">
|
<PackageReference Include="Microsoft.AppCenter.Analytics">
|
||||||
<Version>5.0.4</Version>
|
<Version>5.0.5</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||||
<Version>6.2.14</Version>
|
<Version>6.2.14</Version>
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ namespace Wino.Core.Authenticators
|
|||||||
|
|
||||||
private readonly INativeAppService _nativeAppService;
|
private readonly INativeAppService _nativeAppService;
|
||||||
|
|
||||||
public event EventHandler<string> InteractiveAuthenticationRequired;
|
|
||||||
|
|
||||||
public GmailAuthenticator(ITokenService tokenService, INativeAppService nativeAppService) : base(tokenService)
|
public GmailAuthenticator(ITokenService tokenService, INativeAppService nativeAppService) : base(tokenService)
|
||||||
{
|
{
|
||||||
_nativeAppService = nativeAppService;
|
_nativeAppService = nativeAppService;
|
||||||
|
|||||||
@@ -28,7 +28,16 @@ namespace Wino.Core.Authenticators
|
|||||||
|
|
||||||
public string ClientId { get; } = "b19c2035-d740-49ff-b297-de6ec561b208";
|
public string ClientId { get; } = "b19c2035-d740-49ff-b297-de6ec561b208";
|
||||||
|
|
||||||
private readonly string[] MailScope = ["email", "mail.readwrite", "offline_access", "mail.send", "Mail.Send.Shared", "Mail.ReadWrite.Shared"];
|
private readonly string[] MailScope =
|
||||||
|
[
|
||||||
|
"email",
|
||||||
|
"mail.readwrite",
|
||||||
|
"offline_access",
|
||||||
|
"mail.send",
|
||||||
|
"Mail.Send.Shared",
|
||||||
|
"Mail.ReadWrite.Shared",
|
||||||
|
"User.Read"
|
||||||
|
];
|
||||||
|
|
||||||
public override MailProviderType ProviderType => MailProviderType.Outlook;
|
public override MailProviderType ProviderType => MailProviderType.Outlook;
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ namespace Wino.Core.Extensions
|
|||||||
|
|
||||||
// Some headers also require to start with X- or x-.
|
// Some headers also require to start with X- or x-.
|
||||||
|
|
||||||
string[] headersToIgnore = ["Date", "To", "MIME-Version", "From", "Subject", "Message-Id"];
|
string[] headersToIgnore = ["Date", "To", "Cc", "Bcc", "MIME-Version", "From", "Subject", "Message-Id"];
|
||||||
string[] headersToModify = ["In-Reply-To", "Reply-To", "References", "Thread-Topic"];
|
string[] headersToModify = ["In-Reply-To", "Reply-To", "References", "Thread-Topic"];
|
||||||
|
|
||||||
var headers = new List<InternetMessageHeader>();
|
var headers = new List<InternetMessageHeader>();
|
||||||
@@ -191,15 +191,12 @@ namespace Wino.Core.Extensions
|
|||||||
{
|
{
|
||||||
if (!headersToIgnore.Contains(header.Field))
|
if (!headersToIgnore.Contains(header.Field))
|
||||||
{
|
{
|
||||||
if (headersToModify.Contains(header.Field))
|
var headerName = headersToModify.Contains(header.Field) ? $"X-{header.Field}" : header.Field;
|
||||||
{
|
|
||||||
headers.Add(new InternetMessageHeader() { Name = $"X-{header.Field}", Value = header.Value });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
headers.Add(new InternetMessageHeader() { Name = header.Field, Value = header.Value });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// No header value should exceed 995 characters.
|
||||||
|
var headerValue = header.Value.Length >= 995 ? header.Value.Substring(0, 995) : header.Value;
|
||||||
|
|
||||||
|
headers.Add(new InternetMessageHeader() { Name = headerName, Value = headerValue });
|
||||||
includedHeaderCount++;
|
includedHeaderCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ namespace Wino.Core.Integration.Processors
|
|||||||
{
|
{
|
||||||
Task UpdateAccountAsync(MailAccount account);
|
Task UpdateAccountAsync(MailAccount account);
|
||||||
Task<string> UpdateAccountDeltaSynchronizationIdentifierAsync(Guid accountId, string deltaSynchronizationIdentifier);
|
Task<string> UpdateAccountDeltaSynchronizationIdentifierAsync(Guid accountId, string deltaSynchronizationIdentifier);
|
||||||
Task CreateAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId);
|
|
||||||
Task DeleteAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId);
|
Task DeleteAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId);
|
||||||
Task ChangeMailReadStatusAsync(string mailCopyId, bool isRead);
|
Task ChangeMailReadStatusAsync(string mailCopyId, bool isRead);
|
||||||
Task ChangeFlagStatusAsync(string mailCopyId, bool isFlagged);
|
Task ChangeFlagStatusAsync(string mailCopyId, bool isFlagged);
|
||||||
@@ -53,6 +52,7 @@ namespace Wino.Core.Integration.Processors
|
|||||||
public interface IGmailChangeProcessor : IDefaultChangeProcessor
|
public interface IGmailChangeProcessor : IDefaultChangeProcessor
|
||||||
{
|
{
|
||||||
Task MapLocalDraftAsync(string mailCopyId, string newDraftId, string newThreadId);
|
Task MapLocalDraftAsync(string mailCopyId, string newDraftId, string newThreadId);
|
||||||
|
Task CreateAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IOutlookChangeProcessor : IDefaultChangeProcessor
|
public interface IOutlookChangeProcessor : IDefaultChangeProcessor
|
||||||
@@ -135,8 +135,7 @@ namespace Wino.Core.Integration.Processors
|
|||||||
public Task DeleteAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId)
|
public Task DeleteAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId)
|
||||||
=> MailService.DeleteAssignmentAsync(accountId, mailCopyId, remoteFolderId);
|
=> MailService.DeleteAssignmentAsync(accountId, mailCopyId, remoteFolderId);
|
||||||
|
|
||||||
public Task CreateAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId)
|
|
||||||
=> MailService.CreateAssignmentAsync(accountId, mailCopyId, remoteFolderId);
|
|
||||||
|
|
||||||
public Task DeleteMailAsync(Guid accountId, string mailId)
|
public Task DeleteMailAsync(Guid accountId, string mailId)
|
||||||
=> MailService.DeleteMailAsync(accountId, mailId);
|
=> MailService.DeleteMailAsync(accountId, mailId);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
using Wino.Core.Services;
|
||||||
|
|
||||||
@@ -12,5 +13,8 @@ namespace Wino.Core.Integration.Processors
|
|||||||
|
|
||||||
public Task MapLocalDraftAsync(string mailCopyId, string newDraftId, string newThreadId)
|
public Task MapLocalDraftAsync(string mailCopyId, string newDraftId, string newThreadId)
|
||||||
=> MailService.MapLocalDraftAsync(mailCopyId, newDraftId, newThreadId);
|
=> MailService.MapLocalDraftAsync(mailCopyId, newDraftId, newThreadId);
|
||||||
|
|
||||||
|
public Task CreateAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId)
|
||||||
|
=> MailService.CreateAssignmentAsync(accountId, mailCopyId, remoteFolderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Services;
|
using Wino.Core.Services;
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ namespace Wino.Core.Integration.Threading
|
|||||||
}
|
}
|
||||||
|
|
||||||
///<inheritdoc/>
|
///<inheritdoc/>
|
||||||
public async Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items)
|
public async Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items, IMailItemFolder threadingForFolder)
|
||||||
{
|
{
|
||||||
var assignedAccount = items[0].AssignedAccount;
|
var assignedAccount = items[0].AssignedAccount;
|
||||||
|
|
||||||
@@ -62,11 +63,43 @@ namespace Wino.Core.Integration.Threading
|
|||||||
}
|
}
|
||||||
|
|
||||||
var thread = new ThreadMailItem();
|
var thread = new ThreadMailItem();
|
||||||
|
|
||||||
foreach (var childThreadItem in threadItem)
|
foreach (var childThreadItem in threadItem)
|
||||||
{
|
{
|
||||||
thread.AddThreadItem(childThreadItem);
|
if (thread.ThreadItems.Any(a => a.Id == childThreadItem.Id))
|
||||||
|
{
|
||||||
|
// Mail already exist in the thread.
|
||||||
|
// There should be only 1 instance of the mail in the thread.
|
||||||
|
// Make sure we add the correct one.
|
||||||
|
|
||||||
|
// Add the one with threading folder.
|
||||||
|
var threadingFolderItem = threadItem.FirstOrDefault(a => a.Id == childThreadItem.Id && a.FolderId == threadingForFolder.Id);
|
||||||
|
|
||||||
|
if (threadingFolderItem == null) continue;
|
||||||
|
|
||||||
|
// Remove the existing one.
|
||||||
|
thread.ThreadItems.Remove(thread.ThreadItems.First(a => a.Id == childThreadItem.Id));
|
||||||
|
|
||||||
|
// Add the correct one for listing.
|
||||||
|
thread.AddThreadItem(threadingFolderItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread.AddThreadItem(childThreadItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread.ThreadItems.Count > 1)
|
||||||
|
{
|
||||||
|
resultList.Add(thread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Don't make threads if the thread has only one item.
|
||||||
|
// Gmail has may have multiple assignments for the same item.
|
||||||
|
|
||||||
|
resultList.Add(thread.ThreadItems.First());
|
||||||
}
|
}
|
||||||
resultList.Add(thread);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using SqlKata;
|
using SqlKata;
|
||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Extensions;
|
using Wino.Core.Extensions;
|
||||||
using Wino.Core.Services;
|
using Wino.Core.Services;
|
||||||
@@ -58,7 +59,7 @@ namespace Wino.Core.Integration.Threading
|
|||||||
return _databaseService.Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
return _databaseService.Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items)
|
public async Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items, IMailItemFolder threadingForFolder)
|
||||||
{
|
{
|
||||||
var threads = new List<ThreadMailItem>();
|
var threads = new List<ThreadMailItem>();
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace Wino.Core.Requests
|
|||||||
Items.ForEach(item => WeakReferenceMessenger.Default.Send(new MailAddedMessage(item.Item)));
|
Items.ForEach(item => WeakReferenceMessenger.Default.Send(new MailAddedMessage(item.Item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int ResynchronizationDelay => 10000;
|
public override int ResynchronizationDelay => 6000;
|
||||||
public override bool ExecuteSerialBatch => true;
|
public override bool ExecuteSerialBatch => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ namespace Wino.Core.Services
|
|||||||
|
|
||||||
// Only thread items from Draft and Sent folders must present here.
|
// Only thread items from Draft and Sent folders must present here.
|
||||||
// Otherwise this strategy will fetch the items that are in Deleted folder as well.
|
// Otherwise this strategy will fetch the items that are in Deleted folder as well.
|
||||||
var accountThreadedItems = await threadingStrategy.ThreadItemsAsync([.. group]);
|
var accountThreadedItems = await threadingStrategy.ThreadItemsAsync([.. group], options.Folders.First());
|
||||||
|
|
||||||
// Populate threaded items with folder and account assignments.
|
// Populate threaded items with folder and account assignments.
|
||||||
// Almost everything already should be in cache from initial population.
|
// Almost everything already should be in cache from initial population.
|
||||||
@@ -409,12 +409,11 @@ namespace Wino.Core.Services
|
|||||||
|
|
||||||
foreach (var mailItem in allMails)
|
foreach (var mailItem in allMails)
|
||||||
{
|
{
|
||||||
await DeleteMailInternalAsync(mailItem).ConfigureAwait(false);
|
// Delete mime file as well.
|
||||||
|
|
||||||
// Delete mime file.
|
|
||||||
// Even though Gmail might have multiple copies for the same mail, we only have one MIME file for all.
|
// Even though Gmail might have multiple copies for the same mail, we only have one MIME file for all.
|
||||||
// Their FileId is inserted same.
|
// Their FileId is inserted same.
|
||||||
await _mimeFileService.DeleteMimeMessageAsync(accountId, mailItem.FileId);
|
|
||||||
|
await DeleteMailInternalAsync(mailItem, preserveMimeFile: false).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,7 +456,7 @@ namespace Wino.Core.Services
|
|||||||
ReportUIChange(new MailUpdatedMessage(mailCopy));
|
ReportUIChange(new MailUpdatedMessage(mailCopy));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteMailInternalAsync(MailCopy mailCopy)
|
private async Task DeleteMailInternalAsync(MailCopy mailCopy, bool preserveMimeFile)
|
||||||
{
|
{
|
||||||
if (mailCopy == null)
|
if (mailCopy == null)
|
||||||
{
|
{
|
||||||
@@ -473,7 +472,7 @@ namespace Wino.Core.Services
|
|||||||
// If there are no more copies exists of the same mail, delete the MIME file as well.
|
// If there are no more copies exists of the same mail, delete the MIME file as well.
|
||||||
var isMailExists = await IsMailExistsAsync(mailCopy.Id).ConfigureAwait(false);
|
var isMailExists = await IsMailExistsAsync(mailCopy.Id).ConfigureAwait(false);
|
||||||
|
|
||||||
if (!isMailExists)
|
if (!isMailExists && !preserveMimeFile)
|
||||||
{
|
{
|
||||||
await _mimeFileService.DeleteMimeMessageAsync(mailCopy.AssignedAccount.Id, mailCopy.FileId).ConfigureAwait(false);
|
await _mimeFileService.DeleteMimeMessageAsync(mailCopy.AssignedAccount.Id, mailCopy.FileId).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@@ -554,6 +553,19 @@ namespace Wino.Core.Services
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mailCopy.AssignedFolder.SpecialFolderType == SpecialFolderType.Sent &&
|
||||||
|
localFolder.SpecialFolderType == SpecialFolderType.Deleted)
|
||||||
|
{
|
||||||
|
// Sent item is deleted.
|
||||||
|
// Gmail does not delete the sent items, but moves them to the deleted folder.
|
||||||
|
// API doesn't allow removing Sent label.
|
||||||
|
// Here we intercept this behavior, removing the Sent copy of the mail and adding the Deleted copy.
|
||||||
|
// This way item will only be visible in Trash folder as in Gmail Web UI.
|
||||||
|
// Don't delete MIME file since if exists.
|
||||||
|
|
||||||
|
await DeleteMailInternalAsync(mailCopy, preserveMimeFile: true).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
// Copy one of the mail copy and assign it to the new folder.
|
// Copy one of the mail copy and assign it to the new folder.
|
||||||
// We don't need to create a new MIME pack.
|
// We don't need to create a new MIME pack.
|
||||||
// Therefore FileId is not changed for the new MailCopy.
|
// Therefore FileId is not changed for the new MailCopy.
|
||||||
@@ -585,7 +597,7 @@ namespace Wino.Core.Services
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await DeleteMailInternalAsync(mailItem).ConfigureAwait(false);
|
await DeleteMailInternalAsync(mailItem, preserveMimeFile: false).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> CreateMailAsync(Guid accountId, NewMailItemPackage package)
|
public async Task<bool> CreateMailAsync(Guid accountId, NewMailItemPackage package)
|
||||||
|
|||||||
@@ -595,13 +595,23 @@ namespace Wino.Core.Synchronizers
|
|||||||
{
|
{
|
||||||
return CreateBatchedHttpBundleFromGroup(request, (items) =>
|
return CreateBatchedHttpBundleFromGroup(request, (items) =>
|
||||||
{
|
{
|
||||||
|
// Sent label can't be removed from mails for Gmail.
|
||||||
|
// They are automatically assigned by Gmail.
|
||||||
|
// When you delete sent mail from gmail web portal, it's moved to Trash
|
||||||
|
// but still has Sent label. It's just hidden from the user.
|
||||||
|
// Proper assignments will be done later on CreateAssignment call to mimic this behavior.
|
||||||
var batchModifyRequest = new BatchModifyMessagesRequest
|
var batchModifyRequest = new BatchModifyMessagesRequest
|
||||||
{
|
{
|
||||||
Ids = items.Select(a => a.Item.Id.ToString()).ToList(),
|
Ids = items.Select(a => a.Item.Id.ToString()).ToList(),
|
||||||
AddLabelIds = new[] { request.ToFolder.RemoteFolderId },
|
AddLabelIds = [request.ToFolder.RemoteFolderId]
|
||||||
RemoveLabelIds = new[] { request.FromFolder.RemoteFolderId }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Only add remove label ids if the source folder is not sent folder.
|
||||||
|
if (request.FromFolder.SpecialFolderType != SpecialFolderType.Sent)
|
||||||
|
{
|
||||||
|
batchModifyRequest.RemoveLabelIds = [request.FromFolder.RemoteFolderId];
|
||||||
|
}
|
||||||
|
|
||||||
return _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
return _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -793,6 +803,8 @@ namespace Wino.Core.Synchronizers
|
|||||||
|
|
||||||
var bundleRequestCount = bundle.Count();
|
var bundleRequestCount = bundle.Count();
|
||||||
|
|
||||||
|
var bundleTasks = new List<Task>();
|
||||||
|
|
||||||
for (int k = 0; k < bundleRequestCount; k++)
|
for (int k = 0; k < bundleRequestCount; k++)
|
||||||
{
|
{
|
||||||
var requestBundle = bundle.ElementAt(k);
|
var requestBundle = bundle.ElementAt(k);
|
||||||
@@ -802,37 +814,40 @@ namespace Wino.Core.Synchronizers
|
|||||||
|
|
||||||
request.ApplyUIChanges();
|
request.ApplyUIChanges();
|
||||||
|
|
||||||
// TODO: Queue is synchronous. Create a task bucket to await all processing.
|
nativeBatchRequest.Queue<object>(nativeRequest, (content, error, index, message)
|
||||||
nativeBatchRequest.Queue<object>(nativeRequest, async (content, error, index, message)
|
=> bundleTasks.Add(ProcessSingleNativeRequestResponseAsync(requestBundle, error, message, cancellationToken)));
|
||||||
=> await ProcessSingleNativeRequestResponseAsync(requestBundle, error, message, cancellationToken).ConfigureAwait(false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await nativeBatchRequest.ExecuteAsync(cancellationToken).ConfigureAwait(false);
|
await nativeBatchRequest.ExecuteAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await Task.WhenAll(bundleTasks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessGmailRequestError(RequestError error)
|
private void ProcessGmailRequestError(RequestError error, IRequestBundle<IClientServiceRequest> bundle)
|
||||||
{
|
{
|
||||||
if (error == null) return;
|
if (error == null) return;
|
||||||
|
|
||||||
// OutOfMemoryException is a known bug in Gmail SDK.
|
// OutOfMemoryException is a known bug in Gmail SDK.
|
||||||
if (error.Code == 0)
|
if (error.Code == 0)
|
||||||
{
|
{
|
||||||
|
bundle?.Request.RevertUIChanges();
|
||||||
throw new OutOfMemoryException(error.Message);
|
throw new OutOfMemoryException(error.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entity not found.
|
// Entity not found.
|
||||||
if (error.Code == 404)
|
if (error.Code == 404)
|
||||||
{
|
{
|
||||||
|
bundle?.Request.RevertUIChanges();
|
||||||
throw new SynchronizerEntityNotFoundException(error.Message);
|
throw new SynchronizerEntityNotFoundException(error.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(error.Message))
|
if (!string.IsNullOrEmpty(error.Message))
|
||||||
{
|
{
|
||||||
|
bundle?.Request.RevertUIChanges();
|
||||||
error.Errors?.ForEach(error => _logger.Error("Unknown Gmail SDK error for {Name}\n{Error}", Account.Name, error));
|
error.Errors?.ForEach(error => _logger.Error("Unknown Gmail SDK error for {Name}\n{Error}", Account.Name, error));
|
||||||
|
|
||||||
// TODO: Debug
|
throw new SynchronizerException(error.Message);
|
||||||
// throw new SynchronizerException(error.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,7 +866,7 @@ namespace Wino.Core.Synchronizers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProcessGmailRequestError(error);
|
ProcessGmailRequestError(error, null);
|
||||||
}
|
}
|
||||||
catch (OutOfMemoryException)
|
catch (OutOfMemoryException)
|
||||||
{
|
{
|
||||||
@@ -900,7 +915,7 @@ namespace Wino.Core.Synchronizers
|
|||||||
HttpResponseMessage httpResponseMessage,
|
HttpResponseMessage httpResponseMessage,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
ProcessGmailRequestError(error);
|
ProcessGmailRequestError(error, bundle);
|
||||||
|
|
||||||
if (bundle is HttpRequestBundle<IClientServiceRequest, Message> messageBundle)
|
if (bundle is HttpRequestBundle<IClientServiceRequest, Message> messageBundle)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Graph;
|
using Microsoft.Graph;
|
||||||
using Microsoft.Graph.Models;
|
using Microsoft.Graph.Models;
|
||||||
|
using Microsoft.Graph.Models.ODataErrors;
|
||||||
using Microsoft.Kiota.Abstractions;
|
using Microsoft.Kiota.Abstractions;
|
||||||
using Microsoft.Kiota.Abstractions.Authentication;
|
using Microsoft.Kiota.Abstractions.Authentication;
|
||||||
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware;
|
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware;
|
||||||
@@ -473,13 +474,27 @@ namespace Wino.Core.Synchronizers
|
|||||||
/// <returns>Base64 encoded profile picture.</returns>
|
/// <returns>Base64 encoded profile picture.</returns>
|
||||||
private async Task<string> GetUserProfilePictureAsync()
|
private async Task<string> GetUserProfilePictureAsync()
|
||||||
{
|
{
|
||||||
var photoStream = await _graphClient.Me.Photos["48x48"].Content.GetAsync();
|
try
|
||||||
|
{
|
||||||
|
var photoStream = await _graphClient.Me.Photos["48x48"].Content.GetAsync();
|
||||||
|
|
||||||
using var memoryStream = new MemoryStream();
|
using var memoryStream = new MemoryStream();
|
||||||
await photoStream.CopyToAsync(memoryStream);
|
await photoStream.CopyToAsync(memoryStream);
|
||||||
var byteArray = memoryStream.ToArray();
|
var byteArray = memoryStream.ToArray();
|
||||||
|
|
||||||
return Convert.ToBase64String(byteArray);
|
return Convert.ToBase64String(byteArray);
|
||||||
|
}
|
||||||
|
catch (ODataError odataError) when (odataError.Error.Code == "ImageNotFound")
|
||||||
|
{
|
||||||
|
// Accounts without profile picture will throw this error.
|
||||||
|
// At this point nothing we can do. Just return empty string.
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageReference Include="Google.Apis.Gmail.v1" Version="1.68.0.3427" />
|
<PackageReference Include="Google.Apis.Gmail.v1" Version="1.68.0.3427" />
|
||||||
<PackageReference Include="Google.Apis.PeopleService.v1" Version="1.68.0.3359" />
|
<PackageReference Include="Google.Apis.PeopleService.v1" Version="1.68.0.3359" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.63" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.64" />
|
||||||
<PackageReference Include="HtmlKit" Version="1.1.0" />
|
<PackageReference Include="HtmlKit" Version="1.1.0" />
|
||||||
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
@@ -27,16 +27,16 @@
|
|||||||
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
<PackageReference Include="MailKit" Version="4.7.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Graph" Version="5.56.0" />
|
<PackageReference Include="Microsoft.Graph" Version="5.56.0" />
|
||||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.63.0" />
|
<PackageReference Include="Microsoft.Identity.Client" Version="4.64.0" />
|
||||||
<PackageReference Include="Microsoft.Identity.Client.Broker" Version="4.63.0" />
|
<PackageReference Include="Microsoft.Identity.Client.Broker" Version="4.64.0" />
|
||||||
<PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.63.0" />
|
<PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.64.0" />
|
||||||
<PackageReference Include="MimeKit" Version="4.7.1" />
|
<PackageReference Include="MimeKit" Version="4.7.1" />
|
||||||
<PackageReference Include="morelinq" Version="4.1.0" />
|
<PackageReference Include="morelinq" Version="4.3.0" />
|
||||||
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
|
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
|
||||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
<PackageReference Include="Serilog" Version="4.0.1" />
|
||||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.8" />
|
<PackageReference Include="SkiaSharp" Version="2.88.8" />
|
||||||
<PackageReference Include="SqlKata" Version="2.4.0" />
|
<PackageReference Include="SqlKata" Version="2.4.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ using Wino.Core.Domain.Exceptions;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Navigation;
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
using Wino.Core.Domain.Models.Reader;
|
|
||||||
using Wino.Core.Extensions;
|
using Wino.Core.Extensions;
|
||||||
using Wino.Core.Services;
|
using Wino.Core.Services;
|
||||||
using Wino.Mail.ViewModels.Data;
|
using Wino.Mail.ViewModels.Data;
|
||||||
@@ -89,29 +88,11 @@ namespace Wino.Mail.ViewModels
|
|||||||
public ObservableCollection<AccountContact> CCItems { get; set; } = [];
|
public ObservableCollection<AccountContact> CCItems { get; set; } = [];
|
||||||
public ObservableCollection<AccountContact> BCCItems { get; set; } = [];
|
public ObservableCollection<AccountContact> BCCItems { get; set; } = [];
|
||||||
|
|
||||||
|
|
||||||
public List<EditorToolbarSection> ToolbarSections { get; set; } =
|
|
||||||
[
|
|
||||||
new EditorToolbarSection(){ SectionType = EditorToolbarSectionType.Format },
|
|
||||||
new EditorToolbarSection(){ SectionType = EditorToolbarSectionType.Insert },
|
|
||||||
new EditorToolbarSection(){ SectionType = EditorToolbarSectionType.Draw },
|
|
||||||
new EditorToolbarSection(){ SectionType = EditorToolbarSectionType.Options }
|
|
||||||
];
|
|
||||||
|
|
||||||
private EditorToolbarSection selectedToolbarSection;
|
|
||||||
|
|
||||||
public EditorToolbarSection SelectedToolbarSection
|
|
||||||
{
|
|
||||||
get => selectedToolbarSection;
|
|
||||||
set => SetProperty(ref selectedToolbarSection, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public INativeAppService NativeAppService { get; }
|
public INativeAppService NativeAppService { get; }
|
||||||
|
|
||||||
private readonly IMailService _mailService;
|
private readonly IMailService _mailService;
|
||||||
private readonly ILaunchProtocolService _launchProtocolService;
|
|
||||||
private readonly IMimeFileService _mimeFileService;
|
private readonly IMimeFileService _mimeFileService;
|
||||||
private readonly IFolderService _folderService;
|
private readonly IFolderService _folderService;
|
||||||
private readonly IAccountService _accountService;
|
private readonly IAccountService _accountService;
|
||||||
@@ -123,7 +104,6 @@ namespace Wino.Mail.ViewModels
|
|||||||
|
|
||||||
public ComposePageViewModel(IDialogService dialogService,
|
public ComposePageViewModel(IDialogService dialogService,
|
||||||
IMailService mailService,
|
IMailService mailService,
|
||||||
ILaunchProtocolService launchProtocolService,
|
|
||||||
IMimeFileService mimeFileService,
|
IMimeFileService mimeFileService,
|
||||||
INativeAppService nativeAppService,
|
INativeAppService nativeAppService,
|
||||||
IFolderService folderService,
|
IFolderService folderService,
|
||||||
@@ -141,13 +121,10 @@ namespace Wino.Mail.ViewModels
|
|||||||
|
|
||||||
_folderService = folderService;
|
_folderService = folderService;
|
||||||
_mailService = mailService;
|
_mailService = mailService;
|
||||||
_launchProtocolService = launchProtocolService;
|
|
||||||
_mimeFileService = mimeFileService;
|
_mimeFileService = mimeFileService;
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
_worker = worker;
|
_worker = worker;
|
||||||
_winoServerConnectionManager = winoServerConnectionManager;
|
_winoServerConnectionManager = winoServerConnectionManager;
|
||||||
|
|
||||||
SelectedToolbarSection = ToolbarSections[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
@@ -263,31 +240,6 @@ namespace Wino.Mail.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearCurrentMimeAttachments()
|
|
||||||
{
|
|
||||||
var attachments = new List<MimePart>();
|
|
||||||
var multiparts = new List<Multipart>();
|
|
||||||
var iter = new MimeIterator(CurrentMimeMessage);
|
|
||||||
|
|
||||||
// collect our list of attachments and their parent multiparts
|
|
||||||
while (iter.MoveNext())
|
|
||||||
{
|
|
||||||
var multipart = iter.Parent as Multipart;
|
|
||||||
var part = iter.Current as MimePart;
|
|
||||||
|
|
||||||
if (multipart != null && part != null && part.IsAttachment)
|
|
||||||
{
|
|
||||||
// keep track of each attachment's parent multipart
|
|
||||||
multiparts.Add(multipart);
|
|
||||||
attachments.Add(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now remove each attachment from its parent multipart...
|
|
||||||
for (int i = 0; i < attachments.Count; i++)
|
|
||||||
multiparts[i].Remove(attachments[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveBodyAsync()
|
private async Task SaveBodyAsync()
|
||||||
{
|
{
|
||||||
if (GetHTMLBodyFunction != null)
|
if (GetHTMLBodyFunction != null)
|
||||||
|
|||||||
@@ -221,21 +221,9 @@ namespace Wino.Mail.ViewModels
|
|||||||
|
|
||||||
_themeService.AccentColorChanged -= AccentColorChanged;
|
_themeService.AccentColorChanged -= AccentColorChanged;
|
||||||
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
||||||
_themeService.AccentColorChangedBySystem -= AccentColorChangedBySystem;
|
|
||||||
|
|
||||||
_themeService.AccentColorChanged += AccentColorChanged;
|
_themeService.AccentColorChanged += AccentColorChanged;
|
||||||
_themeService.ElementThemeChanged += ElementThemeChanged;
|
_themeService.ElementThemeChanged += ElementThemeChanged;
|
||||||
_themeService.AccentColorChangedBySystem += AccentColorChangedBySystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AccentColorChangedBySystem(object sender, string newAccentColorHex)
|
|
||||||
{
|
|
||||||
var accentInList = Colors.FirstOrDefault(a => a.IsAccentColor);
|
|
||||||
|
|
||||||
if (accentInList != null)
|
|
||||||
{
|
|
||||||
accentInList.Hex = newAccentColorHex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AccentColorChanged(object sender, string e)
|
private void AccentColorChanged(object sender, string e)
|
||||||
@@ -269,7 +257,6 @@ namespace Wino.Mail.ViewModels
|
|||||||
|
|
||||||
_themeService.AccentColorChanged -= AccentColorChanged;
|
_themeService.AccentColorChanged -= AccentColorChanged;
|
||||||
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
||||||
_themeService.AccentColorChangedBySystem -= AccentColorChangedBySystem;
|
|
||||||
|
|
||||||
if (AppThemes != null)
|
if (AppThemes != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.4" />
|
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.5" />
|
||||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ using Wino.Controls;
|
|||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Reader;
|
|
||||||
|
|
||||||
namespace Wino.Helpers
|
namespace Wino.Helpers
|
||||||
{
|
{
|
||||||
@@ -284,109 +283,60 @@ namespace Wino.Helpers
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Toolbar Section Initialization
|
|
||||||
|
|
||||||
public static Visibility IsFormatSection(EditorToolbarSection section) => section?.SectionType == EditorToolbarSectionType.Format ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
public static Visibility IsInsertSection(EditorToolbarSection section) => section?.SectionType == EditorToolbarSectionType.Insert ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
public static Visibility IsDrawSection(EditorToolbarSection section) => section?.SectionType == EditorToolbarSectionType.Draw ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
public static Visibility IsOptionsSection(EditorToolbarSection section) => section?.SectionType == EditorToolbarSectionType.Options ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Internationalization
|
#region Internationalization
|
||||||
|
|
||||||
public static string GetOperationString(MailOperation operation)
|
public static string GetOperationString(MailOperation operation)
|
||||||
{
|
{
|
||||||
switch (operation)
|
return operation switch
|
||||||
{
|
{
|
||||||
case MailOperation.None:
|
MailOperation.None => "unknown",
|
||||||
return "unknown";
|
MailOperation.Archive => Translator.MailOperation_Archive,
|
||||||
case MailOperation.Archive:
|
MailOperation.UnArchive => Translator.MailOperation_Unarchive,
|
||||||
return Translator.MailOperation_Archive;
|
MailOperation.SoftDelete => Translator.MailOperation_Delete,
|
||||||
case MailOperation.UnArchive:
|
MailOperation.HardDelete => Translator.MailOperation_Delete,
|
||||||
return Translator.MailOperation_Unarchive;
|
MailOperation.Move => Translator.MailOperation_Move,
|
||||||
case MailOperation.SoftDelete:
|
MailOperation.MoveToJunk => Translator.MailOperation_MoveJunk,
|
||||||
return Translator.MailOperation_Delete;
|
MailOperation.MoveToFocused => Translator.MailOperation_MoveFocused,
|
||||||
case MailOperation.HardDelete:
|
MailOperation.MoveToOther => Translator.MailOperation_MoveOther,
|
||||||
return Translator.MailOperation_Delete;
|
MailOperation.AlwaysMoveToOther => Translator.MailOperation_AlwaysMoveOther,
|
||||||
case MailOperation.Move:
|
MailOperation.AlwaysMoveToFocused => Translator.MailOperation_AlwaysMoveFocused,
|
||||||
return Translator.MailOperation_Move;
|
MailOperation.SetFlag => Translator.MailOperation_SetFlag,
|
||||||
case MailOperation.MoveToJunk:
|
MailOperation.ClearFlag => Translator.MailOperation_ClearFlag,
|
||||||
return Translator.MailOperation_MoveJunk;
|
MailOperation.MarkAsRead => Translator.MailOperation_MarkAsRead,
|
||||||
case MailOperation.MoveToFocused:
|
MailOperation.MarkAsUnread => Translator.MailOperation_MarkAsUnread,
|
||||||
return Translator.MailOperation_MoveFocused;
|
MailOperation.MarkAsNotJunk => Translator.MailOperation_MarkNotJunk,
|
||||||
case MailOperation.MoveToOther:
|
MailOperation.Seperator => string.Empty,
|
||||||
return Translator.MailOperation_MoveOther;
|
MailOperation.Ignore => Translator.MailOperation_Ignore,
|
||||||
case MailOperation.AlwaysMoveToOther:
|
MailOperation.Reply => Translator.MailOperation_Reply,
|
||||||
return Translator.MailOperation_AlwaysMoveOther;
|
MailOperation.ReplyAll => Translator.MailOperation_ReplyAll,
|
||||||
case MailOperation.AlwaysMoveToFocused:
|
MailOperation.Zoom => Translator.MailOperation_Zoom,
|
||||||
return Translator.MailOperation_AlwaysMoveFocused;
|
MailOperation.SaveAs => Translator.MailOperation_SaveAs,
|
||||||
case MailOperation.SetFlag:
|
MailOperation.Find => Translator.MailOperation_Find,
|
||||||
return Translator.MailOperation_SetFlag;
|
MailOperation.Forward => Translator.MailOperation_Forward,
|
||||||
case MailOperation.ClearFlag:
|
MailOperation.DarkEditor => string.Empty,
|
||||||
return Translator.MailOperation_ClearFlag;
|
MailOperation.LightEditor => string.Empty,
|
||||||
case MailOperation.MarkAsRead:
|
MailOperation.Print => Translator.MailOperation_Print,
|
||||||
return Translator.MailOperation_MarkAsRead;
|
MailOperation.Navigate => Translator.MailOperation_Navigate,
|
||||||
case MailOperation.MarkAsUnread:
|
_ => "unknown",
|
||||||
return Translator.MailOperation_MarkAsUnread;
|
};
|
||||||
case MailOperation.MarkAsNotJunk:
|
|
||||||
return Translator.MailOperation_MarkNotJunk;
|
|
||||||
case MailOperation.Seperator:
|
|
||||||
return string.Empty;
|
|
||||||
case MailOperation.Ignore:
|
|
||||||
return Translator.MailOperation_Ignore;
|
|
||||||
case MailOperation.Reply:
|
|
||||||
return Translator.MailOperation_Reply;
|
|
||||||
case MailOperation.ReplyAll:
|
|
||||||
return Translator.MailOperation_ReplyAll;
|
|
||||||
case MailOperation.Zoom:
|
|
||||||
return Translator.MailOperation_Zoom;
|
|
||||||
case MailOperation.SaveAs:
|
|
||||||
return Translator.MailOperation_SaveAs;
|
|
||||||
case MailOperation.Find:
|
|
||||||
return Translator.MailOperation_Find;
|
|
||||||
case MailOperation.Forward:
|
|
||||||
return Translator.MailOperation_Forward;
|
|
||||||
case MailOperation.DarkEditor:
|
|
||||||
return string.Empty;
|
|
||||||
case MailOperation.LightEditor:
|
|
||||||
return string.Empty;
|
|
||||||
case MailOperation.Print:
|
|
||||||
return Translator.MailOperation_Print;
|
|
||||||
case MailOperation.Navigate:
|
|
||||||
return Translator.MailOperation_Navigate;
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetOperationString(FolderOperation operation)
|
public static string GetOperationString(FolderOperation operation)
|
||||||
{
|
{
|
||||||
switch (operation)
|
return operation switch
|
||||||
{
|
{
|
||||||
case FolderOperation.None:
|
FolderOperation.None => string.Empty,
|
||||||
break;
|
FolderOperation.Pin => Translator.FolderOperation_Pin,
|
||||||
case FolderOperation.Pin:
|
FolderOperation.Unpin => Translator.FolderOperation_Unpin,
|
||||||
return Translator.FolderOperation_Pin;
|
FolderOperation.MarkAllAsRead => Translator.FolderOperation_MarkAllAsRead,
|
||||||
case FolderOperation.Unpin:
|
FolderOperation.DontSync => Translator.FolderOperation_DontSync,
|
||||||
return Translator.FolderOperation_Unpin;
|
FolderOperation.Empty => Translator.FolderOperation_Empty,
|
||||||
case FolderOperation.MarkAllAsRead:
|
FolderOperation.Rename => Translator.FolderOperation_Rename,
|
||||||
return Translator.FolderOperation_MarkAllAsRead;
|
FolderOperation.Delete => Translator.FolderOperation_Delete,
|
||||||
case FolderOperation.DontSync:
|
FolderOperation.Move => Translator.FolderOperation_Move,
|
||||||
return Translator.FolderOperation_DontSync;
|
FolderOperation.CreateSubFolder => Translator.FolderOperation_CreateSubFolder,
|
||||||
case FolderOperation.Empty:
|
_ => string.Empty,
|
||||||
return Translator.FolderOperation_Empty;
|
};
|
||||||
case FolderOperation.Rename:
|
|
||||||
return Translator.FolderOperation_Rename;
|
|
||||||
case FolderOperation.Delete:
|
|
||||||
return Translator.FolderOperation_Delete;
|
|
||||||
case FolderOperation.Move:
|
|
||||||
return Translator.FolderOperation_Move;
|
|
||||||
case FolderOperation.CreateSubFolder:
|
|
||||||
return Translator.FolderOperation_CreateSubFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:abstract="using:Wino.Views.Abstract"
|
xmlns:abstract="using:Wino.Views.Abstract"
|
||||||
xmlns:controls="using:Wino.Controls"
|
xmlns:controls="using:Wino.Controls"
|
||||||
xmlns:controls1="using:CommunityToolkit.WinUI.Controls"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:data="using:Wino.Mail.ViewModels.Data"
|
xmlns:data="using:Wino.Mail.ViewModels.Data"
|
||||||
xmlns:domain="using:Wino.Core.Domain"
|
xmlns:domain="using:Wino.Core.Domain"
|
||||||
@@ -14,6 +13,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
xmlns:reader="using:Wino.Core.Domain.Models.Reader"
|
xmlns:reader="using:Wino.Core.Domain.Models.Reader"
|
||||||
|
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
|
||||||
x:Name="root"
|
x:Name="root"
|
||||||
d:Background="White"
|
d:Background="White"
|
||||||
Loaded="ComposerLoaded"
|
Loaded="ComposerLoaded"
|
||||||
@@ -144,26 +144,22 @@
|
|||||||
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="56" />
|
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Grid
|
<!-- Format -->
|
||||||
x:Name="TopPanelGrid"
|
<toolkit:TabbedCommandBar>
|
||||||
Padding="16,6,6,6"
|
<toolkit:TabbedCommandBar.Resources>
|
||||||
RowSpacing="6">
|
<SolidColorBrush x:Key="TabContentContentBorderBackground" Color="Transparent" />
|
||||||
<Grid.RowDefinitions>
|
<SolidColorBrush x:Key="TabContentContentBorderBorderBrush" Color="Transparent" />
|
||||||
<RowDefinition Height="Auto" />
|
<Thickness x:Key="TabContentBorderBorderThickness">0</Thickness>
|
||||||
<RowDefinition Height="*" />
|
</toolkit:TabbedCommandBar.Resources>
|
||||||
</Grid.RowDefinitions>
|
<toolkit:TabbedCommandBar.PaneCustomContent>
|
||||||
<CommandBar
|
<toolkit:TabbedCommandBarItem
|
||||||
Grid.Row="1"
|
CommandAlignment="Right"
|
||||||
DefaultLabelPosition="Right"
|
IsDynamicOverflowEnabled="True"
|
||||||
DynamicOverflowItemsChanging="BarDynamicOverflowChanging"
|
OverflowButtonAlignment="Left">
|
||||||
IsDynamicOverflowEnabled="True"
|
|
||||||
OverflowButtonVisibility="Collapsed">
|
|
||||||
<CommandBar.PrimaryCommands>
|
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
Click="InvertComposerThemeClicked"
|
Click="InvertComposerThemeClicked"
|
||||||
LabelPosition="Collapsed"
|
LabelPosition="Collapsed"
|
||||||
@@ -184,252 +180,229 @@
|
|||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
|
|
||||||
<AppBarButton Command="{x:Bind ViewModel.DiscardCommand}" Label="Discard">
|
<AppBarButton Command="{x:Bind ViewModel.DiscardCommand}" Label="{x:Bind domain:Translator.Buttons_Discard}">
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<controls:WinoFontIcon Icon="Delete" />
|
<controls:WinoFontIcon Icon="Delete" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarButton Command="{x:Bind ViewModel.SendCommand}" Label="Send">
|
<AppBarButton Command="{x:Bind ViewModel.SendCommand}" Label="{x:Bind domain:Translator.Buttons_Send}">
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<controls:WinoFontIcon Icon="Send" />
|
<controls:WinoFontIcon Icon="Send" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
</CommandBar.PrimaryCommands>
|
</toolkit:TabbedCommandBarItem>
|
||||||
<CommandBar.Content>
|
</toolkit:TabbedCommandBar.PaneCustomContent>
|
||||||
<!-- Wino Pivot -->
|
<toolkit:TabbedCommandBar.MenuItems>
|
||||||
<controls:WinoPivotControl
|
<toolkit:TabbedCommandBarItem DefaultLabelPosition="Collapsed" Header="{x:Bind domain:Translator.EditorToolbarOption_Format}">
|
||||||
ItemsSource="{x:Bind ViewModel.ToolbarSections}"
|
<AppBarToggleButton
|
||||||
SelectedItem="{x:Bind ViewModel.SelectedToolbarSection, Mode=TwoWay}"
|
x:Name="BoldButton"
|
||||||
SelectorPipeColor="{ThemeResource NavigationViewSelectionIndicatorForeground}">
|
Click="BoldButtonClicked"
|
||||||
<controls:WinoPivotControl.DataTemplate>
|
Label="Bold">
|
||||||
<DataTemplate x:DataType="reader:EditorToolbarSection">
|
<AppBarToggleButton.Icon>
|
||||||
<TextBlock Text="{x:Bind Title}" />
|
<PathIcon Data="{StaticResource BoldPathIcon}" />
|
||||||
</DataTemplate>
|
</AppBarToggleButton.Icon>
|
||||||
</controls:WinoPivotControl.DataTemplate>
|
</AppBarToggleButton>
|
||||||
</controls:WinoPivotControl>
|
<AppBarToggleButton
|
||||||
</CommandBar.Content>
|
x:Name="ItalicButton"
|
||||||
</CommandBar>
|
Click="ItalicButtonClicked"
|
||||||
</Grid>
|
Label="Italic">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource ItalicPathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
<AppBarToggleButton
|
||||||
|
x:Name="UnderlineButton"
|
||||||
|
Click="UnderlineButtonClicked"
|
||||||
|
Label="Underline">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource UnderlinePathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
<AppBarToggleButton
|
||||||
|
x:Name="StrokeButton"
|
||||||
|
Click="StrokeButtonClicked"
|
||||||
|
Label="Stroke">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource StrikePathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
|
||||||
<!-- Editor Options -->
|
<AppBarSeparator />
|
||||||
<Grid Grid.Row="1" Padding="26,0,6,6">
|
|
||||||
<CommandBar
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
DefaultLabelPosition="Collapsed"
|
|
||||||
IsDynamicOverflowEnabled="True"
|
|
||||||
Visibility="{x:Bind helpers:XamlHelpers.IsFormatSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
|
||||||
<AppBarToggleButton
|
|
||||||
x:Name="BoldButton"
|
|
||||||
Click="BoldButtonClicked"
|
|
||||||
Label="Bold">
|
|
||||||
<AppBarToggleButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource BoldPathIcon}" />
|
|
||||||
</AppBarToggleButton.Icon>
|
|
||||||
</AppBarToggleButton>
|
|
||||||
<AppBarToggleButton
|
|
||||||
x:Name="ItalicButton"
|
|
||||||
Click="ItalicButtonClicked"
|
|
||||||
Label="Italic">
|
|
||||||
<AppBarToggleButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource ItalicPathIcon}" />
|
|
||||||
</AppBarToggleButton.Icon>
|
|
||||||
</AppBarToggleButton>
|
|
||||||
<AppBarToggleButton
|
|
||||||
x:Name="UnderlineButton"
|
|
||||||
Click="UnderlineButtonClicked"
|
|
||||||
Label="Underline">
|
|
||||||
<AppBarToggleButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource UnderlinePathIcon}" />
|
|
||||||
</AppBarToggleButton.Icon>
|
|
||||||
</AppBarToggleButton>
|
|
||||||
<AppBarToggleButton
|
|
||||||
x:Name="StrokeButton"
|
|
||||||
Click="StrokeButtonClicked"
|
|
||||||
Label="Stroke">
|
|
||||||
<AppBarToggleButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource StrikePathIcon}" />
|
|
||||||
</AppBarToggleButton.Icon>
|
|
||||||
</AppBarToggleButton>
|
|
||||||
|
|
||||||
<AppBarSeparator />
|
<AppBarToggleButton
|
||||||
|
x:Name="BulletListButton"
|
||||||
|
Click="BulletListButtonClicked"
|
||||||
|
Label="Bullet List">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource BulletedListPathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
|
||||||
<AppBarToggleButton
|
<AppBarToggleButton
|
||||||
x:Name="BulletListButton"
|
x:Name="OrderedListButton"
|
||||||
Click="BulletListButtonClicked"
|
Click="OrderedListButtonClicked"
|
||||||
Label="Bullet List">
|
Label="Ordered List">
|
||||||
<AppBarToggleButton.Icon>
|
<AppBarToggleButton.Icon>
|
||||||
<PathIcon Data="{StaticResource BulletedListPathIcon}" />
|
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
|
||||||
</AppBarToggleButton.Icon>
|
</AppBarToggleButton.Icon>
|
||||||
</AppBarToggleButton>
|
</AppBarToggleButton>
|
||||||
|
|
||||||
<AppBarToggleButton
|
<AppBarSeparator />
|
||||||
x:Name="OrderedListButton"
|
|
||||||
Click="OrderedListButtonClicked"
|
|
||||||
Label="Ordered List">
|
|
||||||
<AppBarToggleButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource OrderedListPathIcon}" />
|
|
||||||
</AppBarToggleButton.Icon>
|
|
||||||
</AppBarToggleButton>
|
|
||||||
|
|
||||||
<AppBarSeparator />
|
<AppBarButton
|
||||||
|
x:Name="DecreaseIndentButton"
|
||||||
|
Click="DecreaseIndentClicked"
|
||||||
|
Label="Outdent">
|
||||||
|
<AppBarButton.Content>
|
||||||
|
<Viewbox Width="16">
|
||||||
|
<PathIcon Data="{StaticResource DecreaseIndentPathIcon}" />
|
||||||
|
</Viewbox>
|
||||||
|
</AppBarButton.Content>
|
||||||
|
</AppBarButton>
|
||||||
|
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
x:Name="DecreaseIndentButton"
|
x:Name="IncreaseIndentButton"
|
||||||
Click="DecreaseIndentClicked"
|
Click="IncreaseIndentClicked"
|
||||||
Label="Outdent">
|
Label="Indent">
|
||||||
<AppBarButton.Content>
|
<AppBarButton.Content>
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource DecreaseIndentPathIcon}" />
|
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
</AppBarButton.Content>
|
</AppBarButton.Content>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
|
|
||||||
<AppBarButton
|
<AppBarElementContainer HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
x:Name="IncreaseIndentButton"
|
<ComboBox
|
||||||
Click="IncreaseIndentClicked"
|
x:Name="AlignmentListView"
|
||||||
Label="Indent">
|
VerticalAlignment="Center"
|
||||||
<AppBarButton.Content>
|
Background="Transparent"
|
||||||
<Viewbox Width="16">
|
BorderBrush="Transparent"
|
||||||
<PathIcon Data="{StaticResource IncreaseIndentPathIcon}" />
|
SelectionChanged="AlignmentChanged">
|
||||||
</Viewbox>
|
<ComboBoxItem IsSelected="True" Tag="left">
|
||||||
</AppBarButton.Content>
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
</AppBarButton>
|
<Viewbox Width="16">
|
||||||
|
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
|
||||||
|
</Viewbox>
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Left}" />
|
||||||
|
</StackPanel>
|
||||||
|
</ComboBoxItem>
|
||||||
|
|
||||||
<AppBarElementContainer HorizontalAlignment="Center" VerticalAlignment="Center">
|
<ComboBoxItem Tag="center">
|
||||||
<ComboBox
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
x:Name="AlignmentListView"
|
<Viewbox Width="16">
|
||||||
VerticalAlignment="Center"
|
<PathIcon Data="{StaticResource AlignCenterPathIcon}" />
|
||||||
Background="Transparent"
|
</Viewbox>
|
||||||
BorderBrush="Transparent"
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Center}" />
|
||||||
SelectionChanged="AlignmentChanged">
|
</StackPanel>
|
||||||
<ComboBoxItem IsSelected="True" Tag="left">
|
</ComboBoxItem>
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource AlignLeftPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Left}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ComboBoxItem>
|
|
||||||
|
|
||||||
<ComboBoxItem Tag="center">
|
<ComboBoxItem Tag="right">
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource AlignCenterPathIcon}" />
|
<PathIcon Data="{StaticResource AlignRightPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Center}" />
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Right}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ComboBoxItem>
|
</ComboBoxItem>
|
||||||
|
|
||||||
<ComboBoxItem Tag="right">
|
<ComboBoxItem Tag="justify">
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
<Viewbox Width="16">
|
<Viewbox Width="16">
|
||||||
<PathIcon Data="{StaticResource AlignRightPathIcon}" />
|
<PathIcon Data="{StaticResource AlignJustifyPathIcon}" />
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Right}" />
|
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Justify}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ComboBoxItem>
|
</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
</AppBarElementContainer>
|
||||||
|
|
||||||
<ComboBoxItem Tag="justify">
|
<AppBarSeparator />
|
||||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
||||||
<Viewbox Width="16">
|
|
||||||
<PathIcon Data="{StaticResource AlignJustifyPathIcon}" />
|
|
||||||
</Viewbox>
|
|
||||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind domain:Translator.Justify}" />
|
|
||||||
</StackPanel>
|
|
||||||
</ComboBoxItem>
|
|
||||||
</ComboBox>
|
|
||||||
</AppBarElementContainer>
|
|
||||||
|
|
||||||
<AppBarSeparator />
|
<AppBarToggleButton
|
||||||
|
x:Name="WebviewToolBarButton"
|
||||||
|
Click="WebViewToggleButtonClicked"
|
||||||
|
Label="{x:Bind domain:Translator.EditorTooltip_WebViewEditor}"
|
||||||
|
ToolTipService.ToolTip="{x:Bind domain:Translator.EditorTooltip_WebViewEditor}">
|
||||||
|
<AppBarToggleButton.Icon>
|
||||||
|
<PathIcon Data="{StaticResource WebviewToolBarPathIcon}" />
|
||||||
|
</AppBarToggleButton.Icon>
|
||||||
|
</AppBarToggleButton>
|
||||||
|
</toolkit:TabbedCommandBarItem>
|
||||||
|
|
||||||
<AppBarToggleButton
|
<!-- Insert -->
|
||||||
x:Name="WebviewToolBarButton"
|
<toolkit:TabbedCommandBarItem Header="{x:Bind domain:Translator.EditorToolbarOption_Insert}">
|
||||||
Click="WebViewToggleButtonClicked"
|
<AppBarButton
|
||||||
Label="{x:Bind domain:Translator.EditorTooltip_WebViewEditor}"
|
x:Name="FilesButton"
|
||||||
ToolTipService.ToolTip="{x:Bind domain:Translator.EditorTooltip_WebViewEditor}">
|
Click="AddFilesClicked"
|
||||||
<AppBarToggleButton.Icon>
|
Label="{x:Bind domain:Translator.Files}">
|
||||||
<PathIcon Data="{StaticResource WebviewToolBarPathIcon}" />
|
<AppBarButton.Icon>
|
||||||
</AppBarToggleButton.Icon>
|
<PathIcon Data="{StaticResource AttachPathIcon}" />
|
||||||
</AppBarToggleButton>
|
</AppBarButton.Icon>
|
||||||
</CommandBar>
|
</AppBarButton>
|
||||||
|
|
||||||
<!-- Insert Panel -->
|
<AppBarButton
|
||||||
<CommandBar
|
x:Name="AddImageButton"
|
||||||
HorizontalAlignment="Left"
|
Click="AddImageClicked"
|
||||||
DefaultLabelPosition="Right"
|
Label="{x:Bind domain:Translator.Photos}">
|
||||||
IsDynamicOverflowEnabled="True"
|
<AppBarButton.Icon>
|
||||||
Visibility="{x:Bind helpers:XamlHelpers.IsInsertSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
<PathIcon Data="{StaticResource AddPhotoPathIcon}" />
|
||||||
<AppBarButton
|
</AppBarButton.Icon>
|
||||||
x:Name="FilesButton"
|
</AppBarButton>
|
||||||
Click="AddFilesClicked"
|
|
||||||
Label="{x:Bind domain:Translator.Files}">
|
|
||||||
<AppBarButton.Icon>
|
|
||||||
<PathIcon Data="{StaticResource AttachPathIcon}" />
|
|
||||||
</AppBarButton.Icon>
|
|
||||||
</AppBarButton>
|
|
||||||
|
|
||||||
<AppBarButton
|
<AppBarButton
|
||||||
x:Name="AddImageButton"
|
x:Name="EmojiButton"
|
||||||
Click="AddImageClicked"
|
Click="EmojiButtonClicked"
|
||||||
Label="{x:Bind domain:Translator.Photos}">
|
Label="{x:Bind domain:Translator.Emoji}">
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<PathIcon Data="{StaticResource AddPhotoPathIcon}" />
|
<PathIcon Data="{StaticResource EmojiPathIcon}" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
|
</toolkit:TabbedCommandBarItem>
|
||||||
|
|
||||||
<AppBarButton
|
<!-- Options -->
|
||||||
x:Name="EmojiButton"
|
<toolkit:TabbedCommandBarItem Header="{x:Bind domain:Translator.EditorToolbarOption_Options}">
|
||||||
Click="EmojiButtonClicked"
|
<AppBarElementContainer>
|
||||||
Label="{x:Bind domain:Translator.Emoji}">
|
<muxc:ToggleSplitButton x:Name="ImportanceSplitButton" IsChecked="{x:Bind ViewModel.IsImportanceSelected, Mode=TwoWay}">
|
||||||
<AppBarButton.Icon>
|
<FontIcon
|
||||||
<PathIcon Data="{StaticResource EmojiPathIcon}" />
|
FontFamily="Segoe Fluent Icons"
|
||||||
</AppBarButton.Icon>
|
FontSize="16"
|
||||||
</AppBarButton>
|
Glyph="" />
|
||||||
</CommandBar>
|
<muxc:ToggleSplitButton.Flyout>
|
||||||
|
<Flyout x:Name="ImportanceFlyout" Placement="Bottom">
|
||||||
<!-- Draw Panel -->
|
<StackPanel Orientation="Horizontal">
|
||||||
<Grid x:Name="DrawPanel" Visibility="{x:Bind helpers:XamlHelpers.IsDrawSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
<StackPanel.Resources>
|
||||||
<TextBlock Text="{x:Bind domain:Translator.ComingSoon}" />
|
<Style TargetType="Button">
|
||||||
</Grid>
|
<Setter Property="Padding" Value="4" />
|
||||||
|
<Setter Property="MinWidth" Value="0" />
|
||||||
<!-- Options Panel -->
|
<Setter Property="MinHeight" Value="0" />
|
||||||
<Grid x:Name="OptionsPanel" Visibility="{x:Bind helpers:XamlHelpers.IsOptionsSection(ViewModel.SelectedToolbarSection), Mode=OneWay}">
|
<Setter Property="Margin" Value="6" />
|
||||||
<muxc:ToggleSplitButton x:Name="ImportanceSplitButton" IsChecked="{x:Bind ViewModel.IsImportanceSelected, Mode=TwoWay}">
|
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||||
<SymbolIcon x:Name="ImportanceSplitButtonContent" Symbol="Important" />
|
</Style>
|
||||||
<muxc:ToggleSplitButton.Flyout>
|
</StackPanel.Resources>
|
||||||
<Flyout x:Name="ImportanceFlyout" Placement="Bottom">
|
<Button Click="ImportanceClicked">
|
||||||
<StackPanel Orientation="Horizontal">
|
<Button.Tag>
|
||||||
<StackPanel.Resources>
|
<mailkit:MessageImportance>High</mailkit:MessageImportance>
|
||||||
<Style TargetType="Button">
|
</Button.Tag>
|
||||||
<Setter Property="Padding" Value="4" />
|
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||||
<Setter Property="MinWidth" Value="0" />
|
</Button>
|
||||||
<Setter Property="MinHeight" Value="0" />
|
<Button Click="ImportanceClicked">
|
||||||
<Setter Property="Margin" Value="6" />
|
<Button.Tag>
|
||||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
<mailkit:MessageImportance>Low</mailkit:MessageImportance>
|
||||||
</Style>
|
</Button.Tag>
|
||||||
</StackPanel.Resources>
|
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||||
<Button Click="ImportanceClicked">
|
</Button>
|
||||||
<Button.Tag>
|
</StackPanel>
|
||||||
<mailkit:MessageImportance>High</mailkit:MessageImportance>
|
</Flyout>
|
||||||
</Button.Tag>
|
</muxc:ToggleSplitButton.Flyout>
|
||||||
<SymbolIcon Symbol="Important" />
|
</muxc:ToggleSplitButton>
|
||||||
</Button>
|
</AppBarElementContainer>
|
||||||
<Button Click="ImportanceClicked">
|
</toolkit:TabbedCommandBarItem>
|
||||||
<Button.Tag>
|
</toolkit:TabbedCommandBar.MenuItems>
|
||||||
<mailkit:MessageImportance>Low</mailkit:MessageImportance>
|
</toolkit:TabbedCommandBar>
|
||||||
</Button.Tag>
|
|
||||||
<SymbolIcon Symbol="Download" />
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
|
||||||
</Flyout>
|
|
||||||
</muxc:ToggleSplitButton.Flyout>
|
|
||||||
</muxc:ToggleSplitButton>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Mime Info -->
|
<!-- Mime Info -->
|
||||||
<Grid
|
<Grid
|
||||||
Grid.Row="2"
|
Grid.Row="1"
|
||||||
Padding="16,0,16,10"
|
Padding="16,0,16,10"
|
||||||
ColumnSpacing="12"
|
ColumnSpacing="12"
|
||||||
RowSpacing="3">
|
RowSpacing="3">
|
||||||
@@ -478,7 +451,7 @@
|
|||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<controls1:TokenizingTextBox
|
<toolkit:TokenizingTextBox
|
||||||
x:Name="ToBox"
|
x:Name="ToBox"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@@ -520,7 +493,7 @@
|
|||||||
Text="Cc: "
|
Text="Cc: "
|
||||||
Visibility="{x:Bind ViewModel.IsCCBCCVisible, Mode=OneWay}" />
|
Visibility="{x:Bind ViewModel.IsCCBCCVisible, Mode=OneWay}" />
|
||||||
|
|
||||||
<controls1:TokenizingTextBox
|
<toolkit:TokenizingTextBox
|
||||||
x:Name="CCBox"
|
x:Name="CCBox"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
@@ -543,7 +516,7 @@
|
|||||||
Text="Bcc: "
|
Text="Bcc: "
|
||||||
Visibility="{x:Bind ViewModel.IsCCBCCVisible, Mode=OneWay}" />
|
Visibility="{x:Bind ViewModel.IsCCBCCVisible, Mode=OneWay}" />
|
||||||
|
|
||||||
<controls1:TokenizingTextBox
|
<toolkit:TokenizingTextBox
|
||||||
x:Name="BccBox"
|
x:Name="BccBox"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
@@ -586,7 +559,7 @@
|
|||||||
SelectionMode="None">
|
SelectionMode="None">
|
||||||
<ListView.ItemsPanel>
|
<ListView.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<controls1:WrapPanel Orientation="Horizontal" />
|
<toolkit:WrapPanel Orientation="Horizontal" />
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ListView.ItemsPanel>
|
</ListView.ItemsPanel>
|
||||||
</ListView>
|
</ListView>
|
||||||
@@ -595,7 +568,7 @@
|
|||||||
<!-- Dropzone -->
|
<!-- Dropzone -->
|
||||||
<Grid
|
<Grid
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.RowSpan="3"
|
Grid.RowSpan="2"
|
||||||
AllowDrop="True"
|
AllowDrop="True"
|
||||||
DragLeave="OnFileDropGridDragLeave"
|
DragLeave="OnFileDropGridDragLeave"
|
||||||
DragOver="OnFileDropGridDragOver"
|
DragOver="OnFileDropGridDragOver"
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ using Windows.UI.Xaml.Media.Animation;
|
|||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
using Wino.Core.Domain.Enums;
|
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Reader;
|
using Wino.Core.Domain.Models.Reader;
|
||||||
using Wino.Extensions;
|
using Wino.Extensions;
|
||||||
@@ -38,7 +37,6 @@ using Wino.Views.Abstract;
|
|||||||
namespace Wino.Views
|
namespace Wino.Views
|
||||||
{
|
{
|
||||||
public sealed partial class ComposePage : ComposePageAbstract,
|
public sealed partial class ComposePage : ComposePageAbstract,
|
||||||
IRecipient<NavigationPaneModeChanged>,
|
|
||||||
IRecipient<CreateNewComposeMailRequested>,
|
IRecipient<CreateNewComposeMailRequested>,
|
||||||
IRecipient<ApplicationThemeChanged>
|
IRecipient<ApplicationThemeChanged>
|
||||||
{
|
{
|
||||||
@@ -170,6 +168,7 @@ namespace Wino.Views
|
|||||||
ViewModel.IsDraggingOverFilesDropZone = false;
|
ViewModel.IsDraggingOverFilesDropZone = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnImageDropGridDragEnter(object sender, DragEventArgs e)
|
private void OnImageDropGridDragEnter(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
bool isValid = false;
|
bool isValid = false;
|
||||||
@@ -557,27 +556,11 @@ namespace Wino.Views
|
|||||||
|
|
||||||
private void DOMLoaded(CoreWebView2 sender, CoreWebView2DOMContentLoadedEventArgs args) => DOMLoadedTask.TrySetResult(true);
|
private void DOMLoaded(CoreWebView2 sender, CoreWebView2DOMContentLoadedEventArgs args) => DOMLoadedTask.TrySetResult(true);
|
||||||
|
|
||||||
void IRecipient<NavigationPaneModeChanged>.Receive(NavigationPaneModeChanged message)
|
|
||||||
{
|
|
||||||
if (message.NewMode == MenuPaneMode.Hidden)
|
|
||||||
TopPanelGrid.Padding = new Thickness(48, 6, 6, 6);
|
|
||||||
else
|
|
||||||
TopPanelGrid.Padding = new Thickness(16, 6, 6, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
async void IRecipient<CreateNewComposeMailRequested>.Receive(CreateNewComposeMailRequested message)
|
async void IRecipient<CreateNewComposeMailRequested>.Receive(CreateNewComposeMailRequested message)
|
||||||
{
|
{
|
||||||
await RenderInternalAsync(message.RenderModel.RenderHtml);
|
await RenderInternalAsync(message.RenderModel.RenderHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BarDynamicOverflowChanging(CommandBar sender, DynamicOverflowItemsChangingEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Action == CommandBarDynamicOverflowAction.AddingToOverflow)
|
|
||||||
sender.OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Visible;
|
|
||||||
else
|
|
||||||
sender.OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowCCBCCClicked(object sender, RoutedEventArgs e)
|
private void ShowCCBCCClicked(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
ViewModel.IsCCBCCVisible = true;
|
ViewModel.IsCCBCCVisible = true;
|
||||||
@@ -641,7 +624,7 @@ namespace Wino.Views
|
|||||||
var selectedImportance = (MessageImportance)senderButton.Tag;
|
var selectedImportance = (MessageImportance)senderButton.Tag;
|
||||||
|
|
||||||
ViewModel.SelectedMessageImportance = selectedImportance;
|
ViewModel.SelectedMessageImportance = selectedImportance;
|
||||||
(ImportanceSplitButton.Content as SymbolIcon).Symbol = (senderButton.Content as SymbolIcon).Symbol;
|
(ImportanceSplitButton.Content as FontIcon).Glyph = (senderButton.Content as FontIcon).Glyph;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Wino.Views
|
|||||||
IRecipient<ShellStateUpdated>,
|
IRecipient<ShellStateUpdated>,
|
||||||
IRecipient<DisposeRenderingFrameRequested>
|
IRecipient<DisposeRenderingFrameRequested>
|
||||||
{
|
{
|
||||||
private const double RENDERING_COLUMN_MIN_WIDTH = 300;
|
private const double RENDERING_COLUMN_MIN_WIDTH = 375;
|
||||||
|
|
||||||
private IStatePersistanceService StatePersistenceService { get; } = App.Current.Services.GetService<IStatePersistanceService>();
|
private IStatePersistanceService StatePersistenceService { get; } = App.Current.Services.GetService<IStatePersistanceService>();
|
||||||
private IKeyPressService KeyPressService { get; } = App.Current.Services.GetService<IKeyPressService>();
|
private IKeyPressService KeyPressService { get; } = App.Current.Services.GetService<IKeyPressService>();
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ namespace Wino.Views
|
|||||||
public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
||||||
IRecipient<HtmlRenderingRequested>,
|
IRecipient<HtmlRenderingRequested>,
|
||||||
IRecipient<CancelRenderingContentRequested>,
|
IRecipient<CancelRenderingContentRequested>,
|
||||||
IRecipient<NavigationPaneModeChanged>,
|
|
||||||
IRecipient<ApplicationThemeChanged>,
|
IRecipient<ApplicationThemeChanged>,
|
||||||
IRecipient<SaveAsPDFRequested>
|
IRecipient<SaveAsPDFRequested>
|
||||||
{
|
{
|
||||||
@@ -208,14 +207,6 @@ namespace Wino.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRecipient<NavigationPaneModeChanged>.Receive(NavigationPaneModeChanged message)
|
|
||||||
{
|
|
||||||
if (message.NewMode == MenuPaneMode.Hidden)
|
|
||||||
RendererBar.Margin = new Thickness(48, 6, 6, 6);
|
|
||||||
else
|
|
||||||
RendererBar.Margin = new Thickness(16, 6, 6, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void WebViewNavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
|
private async void WebViewNavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
|
||||||
{
|
{
|
||||||
// This is our reader.
|
// This is our reader.
|
||||||
|
|||||||
@@ -136,28 +136,31 @@
|
|||||||
<Version>8.2.2</Version>
|
<Version>8.2.2</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Uwp.Animations">
|
<PackageReference Include="CommunityToolkit.Uwp.Animations">
|
||||||
<Version>8.0.240109</Version>
|
<Version>8.1.240821</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Uwp.Behaviors">
|
<PackageReference Include="CommunityToolkit.Uwp.Behaviors">
|
||||||
<Version>8.0.240109</Version>
|
<Version>8.1.240821</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Uwp.Controls.SettingsControls">
|
<PackageReference Include="CommunityToolkit.Uwp.Controls.SettingsControls">
|
||||||
<Version>8.0.240109</Version>
|
<Version>8.1.240821</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Uwp.Controls.Sizers">
|
<PackageReference Include="CommunityToolkit.Uwp.Controls.Sizers">
|
||||||
<Version>8.0.240109</Version>
|
<Version>8.1.240821</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="CommunityToolkit.Uwp.Controls.TabbedCommandBar">
|
||||||
|
<Version>8.1.240821</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Uwp.Controls.TokenizingTextBox">
|
<PackageReference Include="CommunityToolkit.Uwp.Controls.TokenizingTextBox">
|
||||||
<Version>8.0.240109</Version>
|
<Version>8.1.240821</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="EmailValidation">
|
<PackageReference Include="EmailValidation">
|
||||||
<Version>1.2.0</Version>
|
<Version>1.2.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AppCenter.Analytics">
|
<PackageReference Include="Microsoft.AppCenter.Analytics">
|
||||||
<Version>5.0.4</Version>
|
<Version>5.0.5</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AppCenter.Crashes">
|
<PackageReference Include="Microsoft.AppCenter.Crashes">
|
||||||
<Version>5.0.4</Version>
|
<Version>5.0.5</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection">
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection">
|
||||||
<Version>8.0.0</Version>
|
<Version>8.0.0</Version>
|
||||||
@@ -183,16 +186,16 @@
|
|||||||
<Version>5.1.2</Version>
|
<Version>5.1.2</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="ReactiveUI">
|
<PackageReference Include="ReactiveUI">
|
||||||
<Version>19.6.1</Version>
|
<Version>20.1.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Serilog">
|
<PackageReference Include="Serilog">
|
||||||
<Version>3.1.1</Version>
|
<Version>4.0.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Serilog.Exceptions">
|
<PackageReference Include="Serilog.Exceptions">
|
||||||
<Version>8.4.0</Version>
|
<Version>8.4.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="sqlite-net-pcl">
|
<PackageReference Include="sqlite-net-pcl">
|
||||||
<Version>1.8.116</Version>
|
<Version>1.9.172</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Win2D.uwp">
|
<PackageReference Include="Win2D.uwp">
|
||||||
<Version>1.27.1</Version>
|
<Version>1.27.1</Version>
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
using Wino.Core.Domain.Enums;
|
|
||||||
|
|
||||||
namespace Wino.Messaging.Client.Shell
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// When navigation pane mode is changed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="NewMode">New navigation mode.</param>
|
|
||||||
public record NavigationPaneModeChanged(MenuPaneMode NewMode);
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<Identity
|
<Identity
|
||||||
Name="58272BurakKSE.WinoMailPreview"
|
Name="58272BurakKSE.WinoMailPreview"
|
||||||
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
|
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
|
||||||
Version="1.8.3.0" />
|
Version="1.8.5.0" />
|
||||||
|
|
||||||
<Extensions>
|
<Extensions>
|
||||||
<!-- Publisher Cache Folders -->
|
<!-- Publisher Cache Folders -->
|
||||||
|
|||||||
@@ -129,7 +129,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.3233" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1" PrivateAssets="all" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Wino.Mail\Wino.Mail.csproj" />
|
<ProjectReference Include="..\Wino.Mail\Wino.Mail.csproj" />
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.1.2" />
|
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.1.3" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user