Ditch UWP solution completely.

This commit is contained in:
Burak Kaan Köse
2024-07-20 23:32:39 +02:00
parent 654b7ec1a7
commit ebf4bc6f97
378 changed files with 674 additions and 5271 deletions

View File

@@ -1,39 +0,0 @@
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;
}
}
}

View File

@@ -1,154 +0,0 @@
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;
}
}
}

View File

@@ -1,30 +0,0 @@
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;
}
}

View File

@@ -1,76 +0,0 @@
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();
}
}

View File

@@ -1,56 +0,0 @@
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;
}
}
}

View File

@@ -1,84 +0,0 @@
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;
#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;
}
}
}

View File

@@ -1,15 +1,14 @@
<Application
<?xml version="1.0" encoding="utf-8" ?>
<Application
x:Class="Wino.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Wino.Controls"
xmlns:selectors="using:Wino.Selectors"
xmlns:wino="using:Wino">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Styles/Converters.xaml" />
<ResourceDictionary Source="/Styles/FontIcons.xaml" />
<ResourceDictionary Source="/Styles/Colors.xaml" />
@@ -211,6 +210,7 @@
Video="{StaticResource VideoTemplate}" />
</ResourceDictionary>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Define Global Styles here -->

View File

@@ -1,44 +1,33 @@
using System.Collections.Generic;
using System.Linq;
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Activation;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Services;
using Wino.Core.WinUI.Services;
using Wino.Views;
using WinUIEx;
namespace Wino
{
public sealed partial class App : Application
public partial class App : Application
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private WindowEx m_Window;
private Frame m_ShellFrame;
private readonly IApplicationConfiguration _applicationFolderConfiguration;
public App()
{
if (WebAuthenticator.CheckOAuthRedirectionActivation()) return;
InitializeComponent();
UnhandledException += OnAppUnhandledException;
EnteredBackground += OnEnteredBackground;
LeavingBackground += OnLeavingBackground;
Resuming += OnResuming;
Suspending += OnSuspending;
Services = ConfigureServices();
_applicationFolderConfiguration = Services.GetService<IApplicationConfiguration>();
_logInitializer = Services.GetService<ILogInitializer>();
ConfigureLogger();
@@ -46,13 +35,10 @@ namespace Wino
ConfigurePrelaunch();
ConfigureXbox();
_applicationFolderConfiguration = Services.GetService<IApplicationConfiguration>();
// Make sure the paths are setup on app start.
_applicationFolderConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;
_applicationFolderConfiguration.PublisherSharedFolderPath = ApplicationData.Current.GetPublisherCacheFolder(ApplicationConfiguration.SharedFolderName).Path;
_appServiceConnectionManager = Services.GetService<IWinoServerConnectionManager<AppServiceConnection>>();
_themeService = Services.GetService<IThemeService>();
_databaseService = Services.GetService<IDatabaseService>();
_translationService = Services.GetService<ITranslationService>();
@@ -61,166 +47,33 @@ namespace Wino
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
private async void OnResuming(object sender, object e)
{
// App Service connection was lost on suspension.
// We must restore it.
// Server might be running already, but re-launching it will trigger a new connection attempt.
await _appServiceConnectionManager.ConnectAsync();
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
deferral.Complete();
}
private void LogActivation(string log) => Log.Information($"{WinoLaunchLogPrefix}{log}");
private void OnLeavingBackground(object sender, LeavingBackgroundEventArgs e) => LogActivation($"Wino went foreground.");
private void OnEnteredBackground(object sender, EnteredBackgroundEventArgs e) => LogActivation($"Wino went background.");
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
base.OnWindowCreated(args);
_appShellService.AppWindow = args.Window;
LogActivation("Window is created.");
ConfigureTitleBar();
}
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
LogActivation($"OnLaunched -> {args.GetType().Name}, Kind -> {args.Kind}, PreviousExecutionState -> {args.PreviousExecutionState}, IsPrelaunch -> {args.PrelaunchActivated}");
ConfigureWindow();
if (!args.PrelaunchActivated)
{
await ActivateWinoAsync(args);
}
}
_appShellService.AppWindow = m_Window;
protected override async void OnFileActivated(FileActivatedEventArgs args)
{
base.OnFileActivated(args);
Log.Information($"File activation for {args.Files.Count} item(s).");
await ActivateWinoAsync(args);
}
protected override async void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
Log.Information($"OnActivated -> {args.GetType().Name}, Kind -> {args.Kind}, Prev Execution State -> {args.PreviousExecutionState}");
await ActivateWinoAsync(args);
}
protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
base.OnBackgroundActivated(args);
// This can only be handled in App.xaml.cs
// Using handler activation makes it crash at runtime with a COM error...
if (args.TaskInstance.TriggerDetails is AppServiceTriggerDetails appServiceTriggerDetails)
{
// Only accept connections from callers in the same package
if (appServiceTriggerDetails.CallerPackageFamilyName == Package.Current.Id.FamilyName)
{
// Connection established from the fulltrust process
backgroundTaskDeferral = args.TaskInstance.GetDeferral();
args.TaskInstance.Canceled += OnBackgroundTaskCanceled;
_appServiceConnectionManager.Connection = appServiceTriggerDetails.AppServiceConnection;
}
}
LogActivation($"OnBackgroundActivated -> {args.GetType().Name}, TaskInstanceIdName -> {args.TaskInstance?.Task?.Name ?? "NA"}");
await ActivateWinoAsync(args);
}
private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
{
var parameters = new Dictionary<string, string>()
{
{ "BaseMessage", e.Exception.GetBaseException().Message },
{ "BaseStackTrace", e.Exception.GetBaseException().StackTrace },
{ "StackTrace", e.Exception.StackTrace },
{ "Message", e.Exception.Message },
};
Log.Error(e.Exception, "[Wino Crash]");
Crashes.TrackError(e.Exception, parameters);
Analytics.TrackEvent("Wino Crashed", parameters);
}
private bool IsInteractiveLaunchArgs(object args) => args is IActivatedEventArgs;
private async Task ActivateWinoAsync(object args)
{
foreach (var service in initializeServices)
{
await service.InitializeAsync();
}
if (IsInteractiveLaunchArgs(args))
{
if (Window.Current.Content == null)
{
var mainFrame = new Frame();
Window.Current.Content = mainFrame;
await _themeService.InitializeAsync();
}
}
await HandleActivationAsync(args);
if (IsInteractiveLaunchArgs(args))
{
Window.Current.Activate();
LogActivation("Window activated");
}
m_ShellFrame.Navigate(typeof(AppShell));
m_Window.Activate();
}
private async Task HandleActivationAsync(object activationArgs)
private void ConfigureWindow()
{
var activationHandler = GetActivationHandlers().FirstOrDefault(h => h.CanHandle(activationArgs));
if (activationHandler != null)
m_Window = new WindowEx
{
await activationHandler.HandleAsync(activationArgs);
}
SystemBackdrop = new MicaBackdrop(),
ExtendsContentIntoTitleBar = true,
MinWidth = 420
};
if (IsInteractiveLaunchArgs(activationArgs))
{
var defaultHandler = new DefaultActivationHandler();
if (defaultHandler.CanHandle(activationArgs))
{
await defaultHandler.HandleAsync(activationArgs);
}
}
}
m_ShellFrame = new Frame();
public async void OnBackgroundTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
Log.Information($"Background task {sender.Task.Name} was canceled. Reason: {reason}");
await _appServiceConnectionManager.DisconnectAsync();
backgroundTaskDeferral?.Complete();
backgroundTaskDeferral = null;
_appServiceConnectionManager.Connection = null;
m_Window.Content = m_ShellFrame;
}
}
}

View File

@@ -528,6 +528,7 @@
<advanced:WinoAppTitleBar
x:Name="RealAppBar"
Grid.ColumnSpan="2"
Background="Transparent"
BackButtonClicked="BackButtonClicked"
Canvas.ZIndex="150"
CoreWindowText="{x:Bind ViewModel.StatePersistenceService.CoreWindowTitle, Mode=OneWay}"

View File

@@ -4,7 +4,6 @@ using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Wino.Controls;
@@ -31,11 +30,11 @@ using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.Extensions.DependencyInjection;
#endif
@@ -51,19 +50,19 @@ namespace Wino.Views
public AppShell() : base()
{
InitializeComponent();
#if !NET8_0
#if NET8_0
// BackdropMaterial is not available in WinUI 3.0.
// We manually apply it for UWP version only.
SetupMica();
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.LayoutMetricsChanged += TitleBarLayoutUpdated;
//var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
//coreTitleBar.LayoutMetricsChanged += TitleBarLayoutUpdated;
#endif
}
private void TitleBarLayoutUpdated(CoreApplicationViewTitleBar sender, object args) => UpdateTitleBarLayout(sender);
// private void TitleBarLayoutUpdated(CoreApplicationViewTitleBar sender, object args) => UpdateTitleBarLayout(sender);
private void UpdateTitleBarLayout(CoreApplicationViewTitleBar coreTitleBar) => RealAppBar.SystemReserved = coreTitleBar.SystemOverlayRightInset;
//private void UpdateTitleBarLayout(CoreApplicationViewTitleBar coreTitleBar) => RealAppBar.SystemReserved = coreTitleBar.SystemOverlayRightInset;
private async void ItemDroppedOnFolder(object sender, DragEventArgs e)
{

View File

@@ -15,23 +15,23 @@
<!-- Reading Page Date/Name Group Header Background -->
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
<local:AcrylicBrush
<!--<local:AcrylicBrush
x:Key="WinoApplicationBackgroundColor"
BackgroundSource="HostBackdrop"
FallbackColor="#F9F9F9"
TintColor="#FCFCFC"
TintOpacity="0.75" />
TintOpacity="0.75" />-->
</ResourceDictionary>
<ResourceDictionary x:Name="Dark">
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#2C2C2C</SolidColorBrush>
<local:AcrylicBrush
<!--<local:AcrylicBrush
x:Key="WinoApplicationBackgroundColor"
BackgroundSource="HostBackdrop"
FallbackColor="#2C2C2C"
TintColor="#2C2C2C"
TintOpacity="0.30" />
TintOpacity="0.30" />-->
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -1,7 +1,7 @@
<ResourceDictionary
<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">
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>
@@ -23,7 +23,7 @@
<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}" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 B

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,33 +0,0 @@
# 🚀 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)
![Separated UI Zones](https://www.winomail.app/images/separatedzones.png)
## 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.
![Crowdin Contributors](https://www.winomail.app/images/contributors.png)
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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 755 B

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 755 B

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

View File

@@ -2,11 +2,10 @@
using System.Diagnostics;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
using Wino.Core.Messages.Shell;
using Wino.Core.UWP;
using Wino.Mail.ViewModels;
namespace Wino
@@ -35,7 +34,7 @@ namespace Wino
protected BasePage()
{
ViewModel.Dispatcher = new UWPDispatcher(Dispatcher);
ViewModel.Dispatcher = new WinAppDispatcher(DispatcherQueue);
}
~BasePage()

Some files were not shown because too many files have changed in this diff Show More