Removing UWP project.
@@ -1,8 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
|
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
<RootNamespace>Wino.BackgroundTasks.NET8</RootNamespace>
|
<RootNamespace>Wino.BackgroundTasks.NET8</RootNamespace>
|
||||||
|
|
||||||
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) >= 8">win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) >= 8">win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
||||||
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) < 8">win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) < 8">win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MimeKit" Version="4.7.1" />
|
<PackageReference Include="MimeKit" Version="4.7.1" />
|
||||||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<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="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
20
Wino.Core.UWP/WinAppDispatcher.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.WinUI;
|
||||||
|
using Microsoft.UI.Dispatching;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
|
namespace Wino.Core.WinUI
|
||||||
|
{
|
||||||
|
public class WinAppDispatcher : IDispatcher
|
||||||
|
{
|
||||||
|
private readonly DispatcherQueue _dispatcherQueue;
|
||||||
|
|
||||||
|
public WinAppDispatcher(DispatcherQueue dispatcherQueue)
|
||||||
|
{
|
||||||
|
_dispatcherQueue = dispatcherQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ExecuteOnUIThread(Action action) => _dispatcherQueue.EnqueueAsync(() => { action(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
|
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
<RootNamespace>Wino.Core.WinUI</RootNamespace>
|
<RootNamespace>Wino.Core.WinUI</RootNamespace>
|
||||||
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) >= 8">win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) >= 8">win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
||||||
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) < 8">win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)')) < 8">win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Properties\**" />
|
<Compile Remove="Properties\**" />
|
||||||
<Content Remove="Properties\**" />
|
<Content Remove="Properties\**" />
|
||||||
|
|||||||
39
Wino.Mail.WinUI/Activation/ActivationHandler.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Wino.Activation
|
||||||
|
{
|
||||||
|
// For more information on understanding and extending activation flow see
|
||||||
|
// https://github.com/microsoft/TemplateStudio/blob/main/docs/UWP/activation.md
|
||||||
|
internal abstract class ActivationHandler
|
||||||
|
{
|
||||||
|
public abstract bool CanHandle(object args);
|
||||||
|
|
||||||
|
public abstract Task HandleAsync(object args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend this class to implement new ActivationHandlers
|
||||||
|
internal abstract class ActivationHandler<T> : ActivationHandler
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
// Override this method to add the activation logic in your activation handler
|
||||||
|
protected abstract Task HandleInternalAsync(T args);
|
||||||
|
|
||||||
|
public override async Task HandleAsync(object args)
|
||||||
|
{
|
||||||
|
await HandleInternalAsync(args as T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanHandle(object args)
|
||||||
|
{
|
||||||
|
// CanHandle checks the args is of type you have configured
|
||||||
|
return args is T && CanHandleInternal(args as T);
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can override this method to add extra validation on activation args
|
||||||
|
// to determine if your ActivationHandler should handle this activation args
|
||||||
|
protected virtual bool CanHandleInternal(T args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
154
Wino.Mail.WinUI/Activation/BackgroundActivationHandler.cs
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Serilog;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Windows.ApplicationModel.Background;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
|
using Wino.Core.Domain;
|
||||||
|
using Wino.Core.Domain.Enums;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
|
using Wino.Core.UWP.Services;
|
||||||
|
|
||||||
|
#if NET8_0
|
||||||
|
using CommunityToolkit.WinUI.Notifications;
|
||||||
|
#else
|
||||||
|
using Microsoft.Toolkit.Uwp.Notifications;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Wino.Activation
|
||||||
|
{
|
||||||
|
internal class BackgroundActivationHandler : ActivationHandler<BackgroundActivatedEventArgs>
|
||||||
|
{
|
||||||
|
private const string BackgroundExecutionLogTag = "[BackgroundExecution] ";
|
||||||
|
|
||||||
|
private readonly IWinoRequestDelegator _winoRequestDelegator;
|
||||||
|
private readonly INativeAppService _nativeAppService;
|
||||||
|
private readonly IWinoRequestProcessor _winoRequestProcessor;
|
||||||
|
private readonly IWinoServerConnectionManager _winoServerConnectionManager;
|
||||||
|
private readonly IMailService _mailService;
|
||||||
|
private ToastArguments _toastArguments;
|
||||||
|
|
||||||
|
BackgroundTaskDeferral _deferral;
|
||||||
|
public BackgroundActivationHandler(IWinoRequestDelegator winoRequestDelegator,
|
||||||
|
INativeAppService nativeAppService,
|
||||||
|
IWinoRequestProcessor winoRequestProcessor,
|
||||||
|
IWinoServerConnectionManager winoServerConnectionManager,
|
||||||
|
IMailService mailService)
|
||||||
|
{
|
||||||
|
_winoRequestDelegator = winoRequestDelegator;
|
||||||
|
_nativeAppService = nativeAppService;
|
||||||
|
_winoRequestProcessor = winoRequestProcessor;
|
||||||
|
_winoServerConnectionManager = winoServerConnectionManager;
|
||||||
|
_mailService = mailService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task HandleInternalAsync(BackgroundActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
var instance = args.TaskInstance;
|
||||||
|
var taskName = instance.Task.Name;
|
||||||
|
|
||||||
|
instance.Canceled -= OnBackgroundExecutionCanceled;
|
||||||
|
instance.Canceled += OnBackgroundExecutionCanceled;
|
||||||
|
|
||||||
|
_deferral = instance.GetDeferral();
|
||||||
|
|
||||||
|
if (taskName == BackgroundTaskService.ToastActivationTaskEx)
|
||||||
|
{
|
||||||
|
if (instance.TriggerDetails is ToastNotificationActionTriggerDetail toastNotificationActionTriggerDetail)
|
||||||
|
_toastArguments = ToastArguments.Parse(toastNotificationActionTriggerDetail.Argument);
|
||||||
|
|
||||||
|
// All toast activation mail actions are handled here like mark as read or delete.
|
||||||
|
// This should not launch the application on the foreground.
|
||||||
|
|
||||||
|
// Get the action and mail item id.
|
||||||
|
// Prepare package and send to delegator.
|
||||||
|
|
||||||
|
if (_toastArguments.TryGetValue(Constants.ToastMailItemIdKey, out string mailItemId) &&
|
||||||
|
_toastArguments.TryGetValue(Constants.ToastActionKey, out MailOperation action) &&
|
||||||
|
_toastArguments.TryGetValue(Constants.ToastMailItemRemoteFolderIdKey, out string remoteFolderId))
|
||||||
|
{
|
||||||
|
var mailItem = await _mailService.GetSingleMailItemAsync(mailItemId, remoteFolderId);
|
||||||
|
|
||||||
|
if (mailItem == null) return;
|
||||||
|
|
||||||
|
if (_nativeAppService.IsAppRunning())
|
||||||
|
{
|
||||||
|
// Just send the package. We should reflect the UI changes as well.
|
||||||
|
var package = new MailOperationPreperationRequest(action, mailItem);
|
||||||
|
|
||||||
|
await _winoRequestDelegator.ExecuteAsync(package);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need to synchronize changes without reflection the UI changes.
|
||||||
|
|
||||||
|
// var synchronizer = _winoSynchronizerFactory.GetAccountSynchronizer(mailItem.AssignedAccount.Id);
|
||||||
|
var prepRequest = new MailOperationPreperationRequest(action, mailItem);
|
||||||
|
|
||||||
|
var requests = await _winoRequestProcessor.PrepareRequestsAsync(prepRequest);
|
||||||
|
|
||||||
|
foreach (var request in requests)
|
||||||
|
{
|
||||||
|
_winoServerConnectionManager.QueueRequest(request, mailItem.AssignedAccount.Id);
|
||||||
|
|
||||||
|
// synchronizer.QueueRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
//var options = new SynchronizationOptions()
|
||||||
|
//{
|
||||||
|
// Type = SynchronizationType.ExecuteRequests,
|
||||||
|
// AccountId = mailItem.AssignedAccount.Id
|
||||||
|
//};
|
||||||
|
|
||||||
|
//await synchronizer.SynchronizeAsync(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.Canceled -= OnBackgroundExecutionCanceled;
|
||||||
|
|
||||||
|
_deferral.Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBackgroundExecutionCanceled(Windows.ApplicationModel.Background.IBackgroundTaskInstance sender, Windows.ApplicationModel.Background.BackgroundTaskCancellationReason reason)
|
||||||
|
{
|
||||||
|
Log.Error($"{BackgroundExecutionLogTag} ({sender.Task.Name}) Background task is canceled. Reason -> {reason}");
|
||||||
|
|
||||||
|
_deferral?.Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CanHandleInternal(BackgroundActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
var instance = args.TaskInstance;
|
||||||
|
var taskName = instance.Task.Name;
|
||||||
|
|
||||||
|
if (taskName == BackgroundTaskService.ToastActivationTaskEx)
|
||||||
|
{
|
||||||
|
// User clicked Mark as Read or Delete in toast notification.
|
||||||
|
// MailId and Action must present in the arguments.
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//if (instance.TriggerDetails is ToastNotificationActionTriggerDetail toastNotificationActionTriggerDetail)
|
||||||
|
//{
|
||||||
|
// _toastArguments = ToastArguments.Parse(toastNotificationActionTriggerDetail.Argument);
|
||||||
|
|
||||||
|
// return
|
||||||
|
// _toastArguments.Contains(Constants.ToastMailItemIdKey) &&
|
||||||
|
// _toastArguments.Contains(Constants.ToastActionKey);
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (taskName == BackgroundTaskService.BackgroundSynchronizationTimerTaskNameEx)
|
||||||
|
{
|
||||||
|
// This is timer based background synchronization.
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
Wino.Mail.WinUI/Activation/DefaultActivationHandler.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Wino.Views;
|
||||||
|
|
||||||
|
#if NET8_0
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Media.Animation;
|
||||||
|
#else
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Media.Animation;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Wino.Activation
|
||||||
|
{
|
||||||
|
internal class DefaultActivationHandler : ActivationHandler<IActivatedEventArgs>
|
||||||
|
{
|
||||||
|
protected override Task HandleInternalAsync(IActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
(Window.Current.Content as Frame).Navigate(typeof(AppShell), null, new DrillInNavigationTransitionInfo());
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only navigate if Frame content doesn't exist.
|
||||||
|
protected override bool CanHandleInternal(IActivatedEventArgs args)
|
||||||
|
=> (Window.Current?.Content as Frame)?.Content == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
Wino.Mail.WinUI/Activation/FileActivationHandler.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Services;
|
||||||
|
using Wino.Helpers;
|
||||||
|
using Wino.Views;
|
||||||
|
|
||||||
|
#if NET8_0
|
||||||
|
using Microsoft.UI.Xaml.Media.Animation;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
#else
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Media.Animation;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Wino.Activation
|
||||||
|
{
|
||||||
|
internal class FileActivationHandler : ActivationHandler<FileActivatedEventArgs>
|
||||||
|
{
|
||||||
|
private readonly INativeAppService _nativeAppService;
|
||||||
|
private readonly IMimeFileService _mimeFileService;
|
||||||
|
private readonly IStatePersistanceService _statePersistanceService;
|
||||||
|
private readonly IWinoNavigationService _winoNavigationService;
|
||||||
|
|
||||||
|
public FileActivationHandler(INativeAppService nativeAppService,
|
||||||
|
IMimeFileService mimeFileService,
|
||||||
|
IStatePersistanceService statePersistanceService,
|
||||||
|
IWinoNavigationService winoNavigationService)
|
||||||
|
{
|
||||||
|
_nativeAppService = nativeAppService;
|
||||||
|
_mimeFileService = mimeFileService;
|
||||||
|
_statePersistanceService = statePersistanceService;
|
||||||
|
_winoNavigationService = winoNavigationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task HandleInternalAsync(FileActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
// Always handle the last item passed.
|
||||||
|
// Multiple files are not supported.
|
||||||
|
|
||||||
|
var file = args.Files.Last() as StorageFile;
|
||||||
|
|
||||||
|
// Only EML files are supported now.
|
||||||
|
var fileExtension = Path.GetExtension(file.Path);
|
||||||
|
|
||||||
|
if (string.Equals(fileExtension, ".eml", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var fileBytes = await file.ReadBytesAsync();
|
||||||
|
var directoryName = Path.GetDirectoryName(file.Path);
|
||||||
|
|
||||||
|
var messageInformation = await _mimeFileService.GetMimeMessageInformationAsync(fileBytes, directoryName).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (_nativeAppService.IsAppRunning())
|
||||||
|
{
|
||||||
|
// TODO: Activate another Window and go to mail rendering page.
|
||||||
|
_winoNavigationService.NavigateRendering(messageInformation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_statePersistanceService.ShouldShiftMailRenderingDesign = true;
|
||||||
|
|
||||||
|
(Window.Current.Content as Frame).Navigate(typeof(MailRenderingPage), messageInformation, new DrillInNavigationTransitionInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CanHandleInternal(FileActivatedEventArgs args) => args.Files.Any();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
56
Wino.Mail.WinUI/Activation/ProtocolActivationHandler.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Messages.Authorization;
|
||||||
|
using Wino.Core.Messages.Shell;
|
||||||
|
|
||||||
|
namespace Wino.Activation
|
||||||
|
{
|
||||||
|
internal class ProtocolActivationHandler : ActivationHandler<ProtocolActivatedEventArgs>
|
||||||
|
{
|
||||||
|
private const string GoogleAuthorizationProtocolTag = "google.pw.oauth2";
|
||||||
|
private const string MailtoProtocolTag = "mailto:";
|
||||||
|
|
||||||
|
private readonly INativeAppService _nativeAppService;
|
||||||
|
private readonly ILaunchProtocolService _launchProtocolService;
|
||||||
|
|
||||||
|
public ProtocolActivationHandler(INativeAppService nativeAppService, ILaunchProtocolService launchProtocolService)
|
||||||
|
{
|
||||||
|
_nativeAppService = nativeAppService;
|
||||||
|
_launchProtocolService = launchProtocolService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Task HandleInternalAsync(ProtocolActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
// Check URI prefix.
|
||||||
|
|
||||||
|
var protocolString = args.Uri.AbsoluteUri;
|
||||||
|
|
||||||
|
// Google OAuth Response
|
||||||
|
if (protocolString.StartsWith(GoogleAuthorizationProtocolTag))
|
||||||
|
{
|
||||||
|
// App must be working already. No need to check for running state.
|
||||||
|
WeakReferenceMessenger.Default.Send(new ProtocolAuthorizationCallbackReceived(args.Uri));
|
||||||
|
}
|
||||||
|
else if (protocolString.StartsWith(MailtoProtocolTag))
|
||||||
|
{
|
||||||
|
// mailto activation. Try to parse params.
|
||||||
|
|
||||||
|
var replaced = protocolString.Replace(MailtoProtocolTag, "mailto=");
|
||||||
|
replaced = Wino.Core.Extensions.StringExtensions.ReplaceFirst(replaced, "?", "&");
|
||||||
|
|
||||||
|
_launchProtocolService.MailtoParameters = HttpUtility.ParseQueryString(replaced);
|
||||||
|
|
||||||
|
if (_nativeAppService.IsAppRunning())
|
||||||
|
{
|
||||||
|
// Just send publish a message. Shell will continue.
|
||||||
|
WeakReferenceMessenger.Default.Send(new MailtoProtocolMessageRequested());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Serilog;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Wino.Core.Domain;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Messages.Accounts;
|
||||||
|
using Wino.Mail.WinUI;
|
||||||
|
|
||||||
|
|
||||||
|
#if NET8_0
|
||||||
|
using CommunityToolkit.WinUI.Notifications;
|
||||||
|
#else
|
||||||
|
using Microsoft.Toolkit.Uwp.Notifications;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Wino.Activation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This handler will only handle the toasts that runs on foreground.
|
||||||
|
/// Background executions are not handled here like mark as read or delete.
|
||||||
|
/// </summary>
|
||||||
|
internal class ToastNotificationActivationHandler : ActivationHandler<ToastNotificationActivatedEventArgs>
|
||||||
|
{
|
||||||
|
private readonly INativeAppService _nativeAppService;
|
||||||
|
private readonly IMailService _mailService;
|
||||||
|
private readonly IFolderService _folderService;
|
||||||
|
|
||||||
|
private ToastArguments _toastArguments;
|
||||||
|
|
||||||
|
public ToastNotificationActivationHandler(INativeAppService nativeAppService,
|
||||||
|
IMailService mailService,
|
||||||
|
IFolderService folderService)
|
||||||
|
{
|
||||||
|
_nativeAppService = nativeAppService;
|
||||||
|
_mailService = mailService;
|
||||||
|
_folderService = folderService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task HandleInternalAsync(ToastNotificationActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
// Create the mail item navigation event.
|
||||||
|
// If the app is running, it'll be picked up by the Messenger.
|
||||||
|
// Otherwise we'll save it and handle it when the shell loads all accounts.
|
||||||
|
|
||||||
|
// Parse the mail unique id and perform above actions.
|
||||||
|
if (Guid.TryParse(_toastArguments[Constants.ToastMailItemIdKey], out Guid mailItemUniqueId))
|
||||||
|
{
|
||||||
|
var account = await _mailService.GetMailAccountByUniqueIdAsync(mailItemUniqueId).ConfigureAwait(false);
|
||||||
|
if (account == null) return;
|
||||||
|
|
||||||
|
var mailItem = await _mailService.GetSingleMailItemAsync(mailItemUniqueId).ConfigureAwait(false);
|
||||||
|
if (mailItem == null) return;
|
||||||
|
|
||||||
|
var message = new AccountMenuItemExtended(mailItem.AssignedFolder.Id, mailItem);
|
||||||
|
|
||||||
|
// Delegate this event to LaunchProtocolService so app shell can pick it up on launch if app doesn't work.
|
||||||
|
var launchProtocolService = App.Current.Services.GetService<ILaunchProtocolService>();
|
||||||
|
launchProtocolService.LaunchParameter = message;
|
||||||
|
|
||||||
|
// Send the messsage anyways. Launch protocol service will be ignored if the message is picked up by subscriber shell.
|
||||||
|
WeakReferenceMessenger.Default.Send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CanHandleInternal(ToastNotificationActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_toastArguments = ToastArguments.Parse(args.Argument);
|
||||||
|
|
||||||
|
return
|
||||||
|
_toastArguments.Contains(Constants.ToastMailItemIdKey) &&
|
||||||
|
_toastArguments.Contains(Constants.ToastActionKey);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Couldn't handle parsing toast notification arguments for foreground navigate.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<Application
|
<Application
|
||||||
x:Class="Wino.Mail.WinUI.App"
|
x:Class="Wino.Mail.WinUI.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
@@ -8,9 +8,9 @@
|
|||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||||
<!-- Other merged dictionaries here -->
|
<!-- Other merged dictionaries here -->
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
<!-- Other app resources here -->
|
<!-- Other app resources here -->
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -1,50 +1,79 @@
|
|||||||
using System;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using Microsoft.UI.Xaml.Input;
|
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
using Microsoft.UI.Xaml.Navigation;
|
using Windows.Storage;
|
||||||
using Microsoft.UI.Xaml.Shapes;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Windows.ApplicationModel;
|
using Wino.Core.Services;
|
||||||
using Windows.ApplicationModel.Activation;
|
using Wino.Core.WinUI.Services;
|
||||||
using Windows.Foundation;
|
using Wino.Views;
|
||||||
using Windows.Foundation.Collections;
|
using WinUIEx;
|
||||||
|
|
||||||
// To learn more about WinUI, the WinUI project structure,
|
|
||||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
|
||||||
|
|
||||||
namespace Wino.Mail.WinUI
|
namespace Wino.Mail.WinUI
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Provides application-specific behavior to supplement the default Application class.
|
|
||||||
/// </summary>
|
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
/// <summary>
|
private WindowEx m_Window;
|
||||||
/// Initializes the singleton application object. This is the first line of authored code
|
private Frame m_ShellFrame;
|
||||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
|
||||||
/// </summary>
|
private readonly IApplicationConfiguration _applicationFolderConfiguration;
|
||||||
|
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
if (WebAuthenticator.CheckOAuthRedirectionActivation()) return;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
Services = ConfigureServices();
|
||||||
|
|
||||||
|
_applicationFolderConfiguration = Services.GetService<IApplicationConfiguration>();
|
||||||
|
_logInitializer = Services.GetService<ILogInitializer>();
|
||||||
|
|
||||||
|
ConfigureLogger();
|
||||||
|
ConfigureAppCenter();
|
||||||
|
ConfigurePrelaunch();
|
||||||
|
ConfigureXbox();
|
||||||
|
|
||||||
|
// Make sure the paths are setup on app start.
|
||||||
|
_applicationFolderConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;
|
||||||
|
_applicationFolderConfiguration.PublisherSharedFolderPath = ApplicationData.Current.GetPublisherCacheFolder(ApplicationConfiguration.SharedFolderName).Path;
|
||||||
|
|
||||||
|
_themeService = Services.GetService<IThemeService>();
|
||||||
|
_databaseService = Services.GetService<IDatabaseService>();
|
||||||
|
_translationService = Services.GetService<ITranslationService>();
|
||||||
|
_appShellService = Services.GetService<IAppShellService>();
|
||||||
|
|
||||||
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
/// Invoked when the application is launched.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">Details about the launch request and process.</param>
|
|
||||||
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
|
||||||
{
|
{
|
||||||
m_window = new MainWindow();
|
ConfigureWindow();
|
||||||
m_window.Activate();
|
|
||||||
|
_appShellService.AppWindow = m_Window;
|
||||||
|
|
||||||
|
foreach (var service in initializeServices)
|
||||||
|
{
|
||||||
|
await service.InitializeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ShellFrame.Navigate(typeof(AppShell));
|
||||||
|
m_Window.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Window m_window;
|
private void ConfigureWindow()
|
||||||
|
{
|
||||||
|
m_Window = new WindowEx
|
||||||
|
{
|
||||||
|
SystemBackdrop = new MicaBackdrop(),
|
||||||
|
ExtendsContentIntoTitleBar = true,
|
||||||
|
MinWidth = 420
|
||||||
|
};
|
||||||
|
|
||||||
|
m_ShellFrame = new Frame();
|
||||||
|
|
||||||
|
m_Window.Content = m_ShellFrame;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
534
Wino.Mail.WinUI/AppShell.xaml
Normal file
302
Wino.Mail.WinUI/AppShell.xaml.cs
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Windows.ApplicationModel.Core;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Wino.Controls;
|
||||||
|
using Wino.Core.Domain;
|
||||||
|
using Wino.Core.Domain.Entities;
|
||||||
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Folders;
|
||||||
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
|
using Wino.Core.Messages.Accounts;
|
||||||
|
using Wino.Core.Messages.Mails;
|
||||||
|
using Wino.Core.Messages.Shell;
|
||||||
|
using Wino.Extensions;
|
||||||
|
using Wino.Mail.ViewModels.Data;
|
||||||
|
using Wino.MenuFlyouts;
|
||||||
|
using Wino.MenuFlyouts.Context;
|
||||||
|
using Wino.Views.Abstract;
|
||||||
|
|
||||||
|
namespace Wino.Views
|
||||||
|
{
|
||||||
|
public sealed partial class AppShell : AppShellAbstract,
|
||||||
|
IRecipient<AccountMenuItemExtended>,
|
||||||
|
IRecipient<NavigateMailFolderEvent>,
|
||||||
|
IRecipient<CreateNewMailWithMultipleAccountsRequested>,
|
||||||
|
IRecipient<InfoBarMessageRequested>
|
||||||
|
{
|
||||||
|
public AppShell() : base()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
|
||||||
|
coreTitleBar.LayoutMetricsChanged += TitleBarLayoutUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TitleBarLayoutUpdated(CoreApplicationViewTitleBar sender, object args) => UpdateTitleBarLayout(sender);
|
||||||
|
|
||||||
|
private void UpdateTitleBarLayout(CoreApplicationViewTitleBar coreTitleBar) => RealAppBar.SystemReserved = coreTitleBar.SystemOverlayRightInset;
|
||||||
|
|
||||||
|
private async void ItemDroppedOnFolder(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
// Validate package content.
|
||||||
|
if (sender is WinoNavigationViewItem droppedContainer)
|
||||||
|
{
|
||||||
|
droppedContainer.IsDraggingItemOver = false;
|
||||||
|
|
||||||
|
if (CanContinueDragDrop(droppedContainer, e))
|
||||||
|
{
|
||||||
|
if (droppedContainer.DataContext is IBaseFolderMenuItem draggingFolder)
|
||||||
|
{
|
||||||
|
var mailCopies = new List<MailCopy>();
|
||||||
|
|
||||||
|
var dragPackage = e.DataView.Properties[nameof(MailDragPackage)] as MailDragPackage;
|
||||||
|
e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;
|
||||||
|
|
||||||
|
// Extract mail copies from IMailItem.
|
||||||
|
// ThreadViewModels will be divided into pieces.
|
||||||
|
|
||||||
|
foreach (var item in dragPackage.DraggingMails)
|
||||||
|
{
|
||||||
|
if (item is MailItemViewModel singleMailItemViewModel)
|
||||||
|
{
|
||||||
|
mailCopies.Add(singleMailItemViewModel.MailCopy);
|
||||||
|
}
|
||||||
|
else if (item is ThreadMailItemViewModel threadViewModel)
|
||||||
|
{
|
||||||
|
mailCopies.AddRange(threadViewModel.GetMailCopies());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await ViewModel.PerformMoveOperationAsync(mailCopies, draggingFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ItemDragLeaveFromFolder(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is WinoNavigationViewItem leavingContainer)
|
||||||
|
{
|
||||||
|
leavingContainer.IsDraggingItemOver = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanContinueDragDrop(WinoNavigationViewItem interactingContainer, DragEventArgs args)
|
||||||
|
{
|
||||||
|
// TODO: Maybe override caption with some information why the validation failed?
|
||||||
|
// Note: Caption has a max length. It may be trimmed in some languages.
|
||||||
|
|
||||||
|
if (interactingContainer == null || !args.DataView.Properties.ContainsKey(nameof(MailDragPackage))) return false;
|
||||||
|
|
||||||
|
var dragPackage = args.DataView.Properties[nameof(MailDragPackage)] as MailDragPackage;
|
||||||
|
|
||||||
|
// Invalid package.
|
||||||
|
if (!dragPackage.DraggingMails.Any()) return false;
|
||||||
|
|
||||||
|
// Check whether source and target folder are the same.
|
||||||
|
if (interactingContainer.IsSelected) return false;
|
||||||
|
|
||||||
|
// Check if the interacting container is a folder.
|
||||||
|
if (!(interactingContainer.DataContext is IBaseFolderMenuItem folderMenuItem)) return false;
|
||||||
|
|
||||||
|
// Check if the folder is a move target.
|
||||||
|
if (!folderMenuItem.IsMoveTarget) return false;
|
||||||
|
|
||||||
|
// Check whether the moving item's account has at least one same as the target folder's account.
|
||||||
|
var draggedAccountIds = folderMenuItem.HandlingFolders.Select(a => a.MailAccountId);
|
||||||
|
|
||||||
|
if (!dragPackage.DraggingMails.Any(a => draggedAccountIds.Contains(a.AssignedAccount.Id))) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ItemDragEnterOnFolder(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
// Validate package content.
|
||||||
|
if (sender is WinoNavigationViewItem droppedContainer && CanContinueDragDrop(droppedContainer, e))
|
||||||
|
{
|
||||||
|
droppedContainer.IsDraggingItemOver = true;
|
||||||
|
|
||||||
|
var draggingFolder = droppedContainer.DataContext as IBaseFolderMenuItem;
|
||||||
|
|
||||||
|
e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;
|
||||||
|
e.DragUIOverride.Caption = string.Format(Translator.DragMoveToFolderCaption, draggingFolder.FolderName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void Receive(AccountMenuItemExtended message)
|
||||||
|
{
|
||||||
|
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () =>
|
||||||
|
{
|
||||||
|
if (message.FolderId == default) return;
|
||||||
|
|
||||||
|
if (ViewModel.MenuItems.TryGetFolderMenuItem(message.FolderId, out IBaseFolderMenuItem foundMenuItem))
|
||||||
|
{
|
||||||
|
if (foundMenuItem == null) return;
|
||||||
|
|
||||||
|
foundMenuItem.Expand();
|
||||||
|
|
||||||
|
await ViewModel.NavigateFolderAsync(foundMenuItem);
|
||||||
|
|
||||||
|
navigationView.SelectedItem = foundMenuItem;
|
||||||
|
|
||||||
|
if (message.NavigateMailItem == null) return;
|
||||||
|
|
||||||
|
// At this point folder is navigated and items are loaded.
|
||||||
|
WeakReferenceMessenger.Default.Send(new MailItemNavigationRequested(message.NavigateMailItem.UniqueId));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void MenuSelectionChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.SelectedItem is IMenuItem invokedMenuItem)
|
||||||
|
{
|
||||||
|
await ViewModel.MenuItemInvokedOrSelectedAsync(invokedMenuItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void NavigationViewItemInvoked(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs args)
|
||||||
|
{
|
||||||
|
// SelectsOnInvoked is handled in MenuSelectionChanged.
|
||||||
|
// This part is only for the items that are not selectable.
|
||||||
|
if (args.InvokedItemContainer is WinoNavigationViewItem winoNavigationViewItem)
|
||||||
|
{
|
||||||
|
if (winoNavigationViewItem.SelectsOnInvoked) return;
|
||||||
|
|
||||||
|
await ViewModel.MenuItemInvokedOrSelectedAsync(winoNavigationViewItem.DataContext as IMenuItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Receive(NavigateMailFolderEvent message)
|
||||||
|
{
|
||||||
|
if (message.BaseFolderMenuItem == null) return;
|
||||||
|
|
||||||
|
if (navigationView.SelectedItem != message.BaseFolderMenuItem)
|
||||||
|
{
|
||||||
|
var navigateFolderArgs = new NavigateMailFolderEventArgs(message.BaseFolderMenuItem, message.FolderInitLoadAwaitTask);
|
||||||
|
|
||||||
|
ViewModel.NavigationService.NavigateFolder(navigateFolderArgs);
|
||||||
|
|
||||||
|
// Prevent double navigation.
|
||||||
|
navigationView.SelectionChanged -= MenuSelectionChanged;
|
||||||
|
navigationView.SelectedItem = message.BaseFolderMenuItem;
|
||||||
|
navigationView.SelectionChanged += MenuSelectionChanged;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Complete the init task since we are already on the right page.
|
||||||
|
message.FolderInitLoadAwaitTask?.TrySetResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShellFrameContentNavigated(object sender, Microsoft.UI.Xaml.Navigation.NavigationEventArgs e)
|
||||||
|
=> RealAppBar.ShellFrameContent = (e.Content as BasePage).ShellContent;
|
||||||
|
|
||||||
|
private void BackButtonClicked(Controls.Advanced.WinoAppTitleBar sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
WeakReferenceMessenger.Default.Send(new ClearMailSelectionsRequested());
|
||||||
|
WeakReferenceMessenger.Default.Send(new DisposeRenderingFrameRequested());
|
||||||
|
WeakReferenceMessenger.Default.Send(new ShellStateUpdated());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void MenuItemContextRequested(UIElement sender, ContextRequestedEventArgs args)
|
||||||
|
{
|
||||||
|
// Delegate this request to ViewModel.
|
||||||
|
// VM will prepare available actions for this folder and show Menu Flyout.
|
||||||
|
|
||||||
|
if (sender is WinoNavigationViewItem menuItem &&
|
||||||
|
menuItem.DataContext is IBaseFolderMenuItem baseFolderMenuItem &&
|
||||||
|
baseFolderMenuItem.IsMoveTarget &&
|
||||||
|
args.TryGetPosition(sender, out Point p))
|
||||||
|
{
|
||||||
|
args.Handled = true;
|
||||||
|
|
||||||
|
var source = new TaskCompletionSource<FolderOperationMenuItem>();
|
||||||
|
|
||||||
|
var actions = ViewModel.GetFolderContextMenuActions(baseFolderMenuItem);
|
||||||
|
var flyout = new FolderOperationFlyout(actions, source);
|
||||||
|
|
||||||
|
flyout.ShowAt(menuItem, new FlyoutShowOptions()
|
||||||
|
{
|
||||||
|
ShowMode = FlyoutShowMode.Standard,
|
||||||
|
Position = new Point(p.X + 30, p.Y - 20)
|
||||||
|
});
|
||||||
|
|
||||||
|
var operation = await source.Task;
|
||||||
|
|
||||||
|
flyout.Dispose();
|
||||||
|
|
||||||
|
// No action selected.
|
||||||
|
if (operation == null) return;
|
||||||
|
|
||||||
|
await ViewModel.PerformFolderOperationAsync(operation.Operation, baseFolderMenuItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Receive(CreateNewMailWithMultipleAccountsRequested message)
|
||||||
|
{
|
||||||
|
// Find the NewMail menu item container.
|
||||||
|
|
||||||
|
var container = navigationView.ContainerFromMenuItem(ViewModel.CreateMailMenuItem);
|
||||||
|
|
||||||
|
var flyout = new AccountSelectorFlyout(message.AllAccounts, ViewModel.CreateNewMailForAsync);
|
||||||
|
|
||||||
|
flyout.ShowAt(container, new FlyoutShowOptions()
|
||||||
|
{
|
||||||
|
ShowMode = FlyoutShowMode.Auto,
|
||||||
|
Placement = FlyoutPlacementMode.Right
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NavigationPaneOpening(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
|
||||||
|
{
|
||||||
|
// It's annoying that NavigationView doesn't respect expansion state of the items in Minimal display mode.
|
||||||
|
// Expanded items are collaped, and users need to expand them again.
|
||||||
|
// Regardless of the reason, we will expand the selected item if it's a folder with parent account for visibility.
|
||||||
|
|
||||||
|
if (sender.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal && sender.SelectedItem is IFolderMenuItem selectedFolderMenuItem)
|
||||||
|
{
|
||||||
|
selectedFolderMenuItem.Expand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// InfoBar message is requested.
|
||||||
|
/// </summary>
|
||||||
|
public async void Receive(InfoBarMessageRequested message)
|
||||||
|
{
|
||||||
|
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(message.ActionButtonTitle) || message.Action == null)
|
||||||
|
{
|
||||||
|
ShellInfoBar.ActionButton = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShellInfoBar.ActionButton = new Button()
|
||||||
|
{
|
||||||
|
Content = message.ActionButtonTitle,
|
||||||
|
Command = new RelayCommand(message.Action)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellInfoBar.Message = message.Message;
|
||||||
|
ShellInfoBar.Title = message.Title;
|
||||||
|
ShellInfoBar.Severity = message.Severity.AsMUXCInfoBarSeverity();
|
||||||
|
ShellInfoBar.IsOpen = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Wino.Mail.WinUI/AppThemes/Acrylic.xaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:Microsoft.UI.Xaml.Media"
|
||||||
|
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Acrylic</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<!-- Acrylic Template -->
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<!-- Reading Page Date/Name Group Header Background -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#2C2C2C</SolidColorBrush>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
18
Wino.Mail.WinUI/AppThemes/Clouds.xaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Clouds</x:String>
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Clouds.jpg</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b2dffc</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b2dffc</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
47
Wino.Mail.WinUI/AppThemes/Custom.xaml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Custom</x:String>
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appdata:///local/CustomWallpaper.jpg</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<ImageBrush
|
||||||
|
x:Key="WinoApplicationBackgroundColor"
|
||||||
|
ImageSource="{StaticResource ThemeBackgroundImage}"
|
||||||
|
Stretch="UniformToFill" />
|
||||||
|
|
||||||
|
<!-- Navigation View Settings -->
|
||||||
|
<xaml:CornerRadius x:Key="NavigationViewContentGridCornerRadius">0,0,0,0</xaml:CornerRadius>
|
||||||
|
<xaml:CornerRadius x:Key="OverlayCornerRadius">0,1,0,0</xaml:CornerRadius>
|
||||||
|
<Thickness x:Key="NavigationViewContentMargin">0,0,0,0</Thickness>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<!-- Reading Page Date/Name Group Header Background -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
|
||||||
|
|
||||||
|
<Color x:Key="MainCustomThemeColor">#D9FFFFFF</Color>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewExpandedPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewDefaultPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<!-- Reading Page Date/Name Group Header Background -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#1f1f1f</SolidColorBrush>
|
||||||
|
|
||||||
|
<Color x:Key="MainCustomThemeColor">#E61F1F1F</Color>
|
||||||
|
|
||||||
|
<!-- Reading Pane Background -->
|
||||||
|
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewExpandedPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewDefaultPaneBackground" Color="{StaticResource MainCustomThemeColor}" />
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
21
Wino.Mail.WinUI/AppThemes/Forest.xaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:xaml="using:Windows.UI.Xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Forest</x:String>
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Forest.jpg</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#A800D608</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#59001C01</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
18
Wino.Mail.WinUI/AppThemes/Garden.xaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Garden</x:String>
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Garden.jpg</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#dcfad8</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#dcfad8</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
19
Wino.Mail.WinUI/AppThemes/Mica.xaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Mica</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">True</x:Boolean>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="WinoApplicationBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<!-- Mica Template -->
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<!-- Reading Page Date/Name Group Header Background -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#1f1f1f</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
20
Wino.Mail.WinUI/AppThemes/Nighty.xaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Nighty</x:String>
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Nighty.jpg</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<!-- Brushes -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#fdcb6e</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<!-- Brushes -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#5413191F</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
20
Wino.Mail.WinUI/AppThemes/Snowflake.xaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">Snowflake</x:String>
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Snowflake.jpg</x:String>
|
||||||
|
<x:Boolean x:Key="UseMica">False</x:Boolean>
|
||||||
|
|
||||||
|
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||||
|
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<!-- Brushes -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b0c6dd</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<!-- Brushes -->
|
||||||
|
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b0c6dd</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
22
Wino.Mail.WinUI/AppThemes/TestTheme.xaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<x:String x:Key="ThemeName">TestTheme.xaml</x:String>
|
||||||
|
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Name="Light">
|
||||||
|
<!-- Background Image -->
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/bg6.jpg</x:String>
|
||||||
|
<SolidColorBrush x:Key="ShellTitleBarBackgroundColorBrush">#A3FFFFFF</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="ShellNavigationViewBackgroundColorBrush">#A3FFFFFF</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush">#fdcb6e</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Name="Dark">
|
||||||
|
<!-- Background Image -->
|
||||||
|
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/bg6.jpg</x:String>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="ShellTitleBarBackgroundColorBrush">#A3000000</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="ShellNavigationViewBackgroundColorBrush">#A3000000</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush">#A3262626</SolidColorBrush>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
BIN
Wino.Mail.WinUI/Assets/BadgeLogo.scale-100.png
Normal file
|
After Width: | Height: | Size: 209 B |
BIN
Wino.Mail.WinUI/Assets/BadgeLogo.scale-125.png
Normal file
|
After Width: | Height: | Size: 238 B |
BIN
Wino.Mail.WinUI/Assets/BadgeLogo.scale-150.png
Normal file
|
After Width: | Height: | Size: 286 B |
BIN
Wino.Mail.WinUI/Assets/BadgeLogo.scale-200.png
Normal file
|
After Width: | Height: | Size: 360 B |
BIN
Wino.Mail.WinUI/Assets/BadgeLogo.scale-400.png
Normal file
|
After Width: | Height: | Size: 673 B |
BIN
Wino.Mail.WinUI/Assets/EML/eml.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_archive.png
Normal file
|
After Width: | Height: | Size: 348 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_audio.png
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_executable.png
Normal file
|
After Width: | Height: | Size: 678 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_html.png
Normal file
|
After Width: | Height: | Size: 591 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_image.png
Normal file
|
After Width: | Height: | Size: 599 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_none.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_other.png
Normal file
|
After Width: | Height: | Size: 256 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_pdf.png
Normal file
|
After Width: | Height: | Size: 712 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_rar.png
Normal file
|
After Width: | Height: | Size: 621 B |
BIN
Wino.Mail.WinUI/Assets/FileTypes/type_video.png
Normal file
|
After Width: | Height: | Size: 413 B |
BIN
Wino.Mail.WinUI/Assets/LargeTile.scale-100.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
Wino.Mail.WinUI/Assets/LargeTile.scale-125.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Wino.Mail.WinUI/Assets/LargeTile.scale-150.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
Wino.Mail.WinUI/Assets/LargeTile.scale-200.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
Wino.Mail.WinUI/Assets/LargeTile.scale-400.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
Wino.Mail.WinUI/Assets/NotificationIcons/delete.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
Wino.Mail.WinUI/Assets/NotificationIcons/dismiss.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
Wino.Mail.WinUI/Assets/NotificationIcons/markread.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
Wino.Mail.WinUI/Assets/NotificationIcons/profile-dark.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Wino.Mail.WinUI/Assets/NotificationIcons/profile-light.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
Wino.Mail.WinUI/Assets/Providers/Gmail.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
Wino.Mail.WinUI/Assets/Providers/IMAP4.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
Wino.Mail.WinUI/Assets/Providers/Office 365.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
Wino.Mail.WinUI/Assets/Providers/Outlook.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
Wino.Mail.WinUI/Assets/Providers/Yahoo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
33
Wino.Mail.WinUI/Assets/ReleaseNotes/176.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# 🚀 Welcome to Wino Mail 1.7.6
|
||||||
|
|
||||||
|
This version brings bunch of UI improvements and bugfixes on top of the added features thanks to our community members.
|
||||||
|
|
||||||
|
## Separated UI Zones
|
||||||
|
|
||||||
|
Community liked the proposed designs for separated UI parts and it's implemented now thanks to [Tiktack](https://github.com/Tiktack)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Including Conversation History for Replies and Forwards
|
||||||
|
|
||||||
|
Previously when you replied to an e-mail conversation history was not included into new draft. This was a limitation due to Quill editor we use as a composer editor but now thanks to [Tiktack](https://github.com/Tiktack) Wino now uses Jodit editor as a composer. It's able to render HTML as it is better.
|
||||||
|
|
||||||
|
## HTML Signatures
|
||||||
|
|
||||||
|
You can now copy your signature as HTML and paste directly into signature editor. This was asked by community and now is possible with the new Jodit composer.
|
||||||
|
|
||||||
|
## Reworked Menu System
|
||||||
|
|
||||||
|
Merged accounts will not list individual accounts below instead of inside the More folder menu item.
|
||||||
|
|
||||||
|
## New IMAP and Gmail Folder Synchronization
|
||||||
|
|
||||||
|
IMAP and Gmail folder synchronization mechanism is reworked. New code works faster and fixed couple parent-child relation issues with the folder. I hope this will also resolve a lot of people complaining some Gmail folders are not visible for them after the initial sync.
|
||||||
|
|
||||||
|
## New Languages
|
||||||
|
|
||||||
|
Thanks to our amazing community members Wino has more languages supported in this version with the help of Crowdin contributors.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Some of the translations are not completed yet, and Wino will fallback to English strings in case of the translation has not been translated yet.
|
||||||
BIN
Wino.Mail.WinUI/Assets/SmallTile.scale-100.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
Wino.Mail.WinUI/Assets/SmallTile.scale-125.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
Wino.Mail.WinUI/Assets/SmallTile.scale-150.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Wino.Mail.WinUI/Assets/SmallTile.scale-200.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
Wino.Mail.WinUI/Assets/SmallTile.scale-400.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Wino.Mail.WinUI/Assets/SplashScreen.scale-100.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
Wino.Mail.WinUI/Assets/SplashScreen.scale-125.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
Wino.Mail.WinUI/Assets/SplashScreen.scale-150.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 28 KiB |
BIN
Wino.Mail.WinUI/Assets/SplashScreen.scale-400.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
Wino.Mail.WinUI/Assets/Square150x150Logo.scale-100.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
Wino.Mail.WinUI/Assets/Square150x150Logo.scale-125.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Wino.Mail.WinUI/Assets/Square150x150Logo.scale-150.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 8.5 KiB |
BIN
Wino.Mail.WinUI/Assets/Square150x150Logo.scale-400.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 755 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 755 B |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.scale-100.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.scale-125.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.scale-150.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 4.2 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.scale-400.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.targetsize-16.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.targetsize-24.png
Normal file
|
After Width: | Height: | Size: 962 B |
|
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 1.2 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.targetsize-256.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.targetsize-32.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Wino.Mail.WinUI/Assets/Square44x44Logo.targetsize-48.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Wino.Mail.WinUI/Assets/StoreLogo.backup.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Wino.Mail.WinUI/Assets/StoreLogo.scale-100.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
Wino.Mail.WinUI/Assets/StoreLogo.scale-125.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Wino.Mail.WinUI/Assets/StoreLogo.scale-150.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Wino.Mail.WinUI/Assets/StoreLogo.scale-200.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
Wino.Mail.WinUI/Assets/StoreLogo.scale-400.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
Wino.Mail.WinUI/Assets/Thumbnails/airbnb.com.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
Wino.Mail.WinUI/Assets/Thumbnails/apple.com.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Wino.Mail.WinUI/Assets/Thumbnails/google.com.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |