Wino.Server and Wino.Packaging projects. Enabling full trust for UWP and app service connection manager basics.

This commit is contained in:
Burak Kaan Köse
2024-07-16 23:28:57 +02:00
parent 3b8454269e
commit ec4162e71f
141 changed files with 799 additions and 116 deletions

View File

@@ -0,0 +1,11 @@
namespace Wino.Core.Domain.Enums
{
public enum WinoServerConnectionStatus
{
None,
Connecting,
Connected,
Disconnected,
Failed
}
}

View File

@@ -6,5 +6,5 @@
/// They are sent either from processor or view models to signal some other /// They are sent either from processor or view models to signal some other
/// parts of the application. /// parts of the application.
/// </summary> /// </summary>
public interface IUIMessage; public interface IServerMessage;
} }

View File

@@ -0,0 +1,17 @@
using System.Threading.Tasks;
using Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Interfaces
{
public interface IWinoServerConnectionManager
{
WinoServerConnectionStatus Status { get; }
Task<bool> ConnectAsync();
Task<bool> DisconnectAsync();
}
public interface IWinoServerConnectionManager<TAppServiceConnection> : IWinoServerConnectionManager, IInitializeAsync
{
TAppServiceConnection Connection { get; set; }
}
}

View File

@@ -70,4 +70,7 @@
<LastGenOutput>Translator.Designer.cs</LastGenOutput> <LastGenOutput>Translator.Designer.cs</LastGenOutput>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Models\Communication\" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Windows.ApplicationModel.AppService;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP.Services; using Wino.Core.UWP.Services;
using Wino.Services; using Wino.Services;
@@ -9,6 +10,11 @@ namespace Wino.Core.UWP
{ {
public static void RegisterCoreUWPServices(this IServiceCollection services) public static void RegisterCoreUWPServices(this IServiceCollection services)
{ {
var serverConnectionManager = new WinoServerConnectionManager();
services.AddSingleton<IWinoServerConnectionManager>(serverConnectionManager);
services.AddSingleton<IWinoServerConnectionManager<AppServiceConnection>>(serverConnectionManager);
services.AddSingleton<IUnderlyingThemeService, UnderlyingThemeService>(); services.AddSingleton<IUnderlyingThemeService, UnderlyingThemeService>();
services.AddSingleton<INativeAppService, NativeAppService>(); services.AddSingleton<INativeAppService, NativeAppService>();
services.AddSingleton<IStoreManagementService, StoreManagementService>(); services.AddSingleton<IStoreManagementService, StoreManagementService>();

View File

@@ -167,6 +167,7 @@ namespace Wino.Services
await ApplyCustomThemeAsync(true); await ApplyCustomThemeAsync(true);
// Registering to color changes, thus we notice when user changes theme system wide // Registering to color changes, thus we notice when user changes theme system wide
uiSettings.ColorValuesChanged -= UISettingsColorChanged;
uiSettings.ColorValuesChanged += UISettingsColorChanged; uiSettings.ColorValuesChanged += UISettingsColorChanged;
} }

View File

@@ -0,0 +1,59 @@
using System;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using Windows.ApplicationModel.AppService;
using Windows.Foundation.Metadata;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
namespace Wino.Core.UWP.Services
{
public partial class WinoServerConnectionManager : ObservableObject, IWinoServerConnectionManager<AppServiceConnection>
{
public AppServiceConnection Connection { get; set; }
private Guid? _activeConnectionSessionId;
[ObservableProperty]
private WinoServerConnectionStatus _status;
public async Task<bool> ConnectAsync()
{
if (Status == WinoServerConnectionStatus.Connected) return true;
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
try
{
Status = WinoServerConnectionStatus.Connecting;
// await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
}
catch (Exception)
{
return false;
}
return true;
}
return false;
}
public async Task<bool> DisconnectAsync()
{
if (Connection == null || Status == WinoServerConnectionStatus.Disconnected) return true;
// TODO: Send disconnect message to the fulltrust process.
return true;
}
public async Task InitializeAsync()
{
var isConnectionSuccessfull = await ConnectAsync();
// TODO: Log connection status
}
}
}

View File

@@ -118,6 +118,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<LangVersion>12.0</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CoreUWPContainerSetup.cs" /> <Compile Include="CoreUWPContainerSetup.cs" />
@@ -128,6 +129,7 @@
<Compile Include="Models\Personalization\SystemAppTheme.cs" /> <Compile Include="Models\Personalization\SystemAppTheme.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\AppInitializerService.cs" /> <Compile Include="Services\AppInitializerService.cs" />
<Compile Include="Services\WinoServerConnectionManager.cs" />
<Compile Include="Services\BackgroundSynchronizer.cs" /> <Compile Include="Services\BackgroundSynchronizer.cs" />
<Compile Include="Services\BackgroundTaskService.cs" /> <Compile Include="Services\BackgroundTaskService.cs" />
<Compile Include="Services\ClipboardService.cs" /> <Compile Include="Services\ClipboardService.cs" />
@@ -169,7 +171,11 @@
<Name>Wino.Core</Name> <Name>Wino.Core</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion> <VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -5,6 +5,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -5,6 +5,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -2,6 +2,7 @@
using Wino.Core.Domain.Entities; using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -7,6 +7,7 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Requests;
using Wino.Messages.Server;
namespace Wino.Core.Requests namespace Wino.Core.Requests
{ {

View File

@@ -10,9 +10,9 @@ using SqlKata;
using Wino.Core.Domain.Entities; using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Extensions; using Wino.Core.Extensions;
using Wino.Core.Messages.Accounts; using Wino.Core.Messages.Accounts;
using Wino.Messages.Server;
namespace Wino.Core.Services namespace Wino.Core.Services
{ {

View File

@@ -16,7 +16,7 @@ namespace Wino.Core.Services
_databaseService = databaseService; _databaseService = databaseService;
} }
public void ReportUIChange<TMessage>(TMessage message) where TMessage : class, IUIMessage public void ReportUIChange<TMessage>(TMessage message) where TMessage : class, IServerMessage
=> Messenger.Send(message); => Messenger.Send(message);
} }
} }

View File

@@ -13,10 +13,10 @@ using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Accounts;
using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Extensions; using Wino.Core.Extensions;
using Wino.Core.MenuItems; using Wino.Core.MenuItems;
using Wino.Messages.Server;
namespace Wino.Core.Services namespace Wino.Core.Services
{ {

View File

@@ -13,8 +13,8 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Comparers; using Wino.Core.Domain.Models.Comparers;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Extensions; using Wino.Core.Extensions;
using Wino.Messages.Server;
namespace Wino.Core.Services namespace Wino.Core.Services
{ {

View File

@@ -5,15 +5,14 @@ using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging;
using Wino.Core;
using Wino.Core.Domain; using Wino.Core.Domain;
using Wino.Core.Domain.Entities; using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Messages.Navigation; using Wino.Core.Messages.Navigation;
using Wino.Messages.Server;
namespace Wino.Mail.ViewModels namespace Wino.Mail.ViewModels
{ {

View File

@@ -15,12 +15,12 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Exceptions; using Wino.Core.Domain.Exceptions;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Domain.Models.Store; using Wino.Core.Domain.Models.Store;
using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Messages.Authorization; using Wino.Core.Messages.Authorization;
using Wino.Core.Messages.Navigation; using Wino.Core.Messages.Navigation;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
using Wino.Messages.Server;
namespace Wino.Mail.ViewModels namespace Wino.Mail.ViewModels
{ {

View File

@@ -18,7 +18,6 @@ using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.MenuItems; using Wino.Core.MenuItems;
using Wino.Core.Messages.Accounts; using Wino.Core.Messages.Accounts;
@@ -27,6 +26,7 @@ using Wino.Core.Messages.Navigation;
using Wino.Core.Messages.Shell; using Wino.Core.Messages.Shell;
using Wino.Core.Messages.Synchronization; using Wino.Core.Messages.Synchronization;
using Wino.Core.Services; using Wino.Core.Services;
using Wino.Messages.Server;
namespace Wino.Mail.ViewModels namespace Wino.Mail.ViewModels
{ {
@@ -62,6 +62,7 @@ namespace Wino.Mail.ViewModels
#endregion #endregion
public IStatePersistanceService StatePersistenceService { get; } public IStatePersistanceService StatePersistenceService { get; }
public IWinoServerConnectionManager ServerConnectionManager { get; }
public IPreferencesService PreferencesService { get; } public IPreferencesService PreferencesService { get; }
public IWinoNavigationService NavigationService { get; } public IWinoNavigationService NavigationService { get; }
@@ -97,9 +98,12 @@ namespace Wino.Mail.ViewModels
INotificationBuilder notificationBuilder, INotificationBuilder notificationBuilder,
IWinoRequestDelegator winoRequestDelegator, IWinoRequestDelegator winoRequestDelegator,
IFolderService folderService, IFolderService folderService,
IStatePersistanceService statePersistanceService) : base(dialogService) IStatePersistanceService statePersistanceService,
IWinoServerConnectionManager serverConnectionManager) : base(dialogService)
{ {
StatePersistenceService = statePersistanceService; StatePersistenceService = statePersistanceService;
ServerConnectionManager = serverConnectionManager;
PreferencesService = preferencesService; PreferencesService = preferencesService;
NavigationService = navigationService; NavigationService = navigationService;

View File

@@ -6,7 +6,7 @@ using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Requests; using Wino.Messages.Server;
namespace Wino.Mail.ViewModels namespace Wino.Mail.ViewModels
{ {
@@ -71,7 +71,7 @@ namespace Wino.Mail.ViewModels
protected virtual void OnFolderRenamed(IMailItemFolder mailItemFolder) { } protected virtual void OnFolderRenamed(IMailItemFolder mailItemFolder) { }
protected virtual void OnFolderSynchronizationEnabled(IMailItemFolder mailItemFolder) { } protected virtual void OnFolderSynchronizationEnabled(IMailItemFolder mailItemFolder) { }
public void ReportUIChange<TMessage>(TMessage message) where TMessage : class, IUIMessage public void ReportUIChange<TMessage>(TMessage message) where TMessage : class, IServerMessage
=> Messenger.Send(message); => Messenger.Send(message);
void IRecipient<AccountCreatedMessage>.Receive(AccountCreatedMessage message) => OnAccountCreated(message.Account); void IRecipient<AccountCreatedMessage>.Receive(AccountCreatedMessage message) => OnAccountCreated(message.Account);

View File

@@ -8,9 +8,9 @@ using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain; using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Messages.Navigation; using Wino.Core.Messages.Navigation;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
using Wino.Messages.Server;
namespace Wino.Mail.ViewModels namespace Wino.Mail.ViewModels
{ {

View File

@@ -0,0 +1,41 @@
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.AppService;
using Wino.Core.Domain.Interfaces;
namespace Wino.Activation
{
internal class BackgroundActivationHandlerEx : ActivationHandler<BackgroundActivatedEventArgs>
{
private readonly IWinoServerConnectionManager<AppServiceConnection> _winoServerConnectionManager;
public BackgroundActivationHandlerEx(IWinoServerConnectionManager<AppServiceConnection> winoServerConnectionManager)
{
_winoServerConnectionManager = winoServerConnectionManager;
}
protected override Task HandleInternalAsync(BackgroundActivatedEventArgs args)
{
if (args.TaskInstance == null || args.TaskInstance.TriggerDetails == null) return Task.CompletedTask;
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
_winoServerConnectionManager.Connection = appServiceTriggerDetails.AppServiceConnection;
var deferral = args.TaskInstance.GetDeferral();
args.TaskInstance.Canceled += App.Current.OnBackgroundTaskCanceled;
// AppServiceConnected?.Invoke(this, args.TaskInstance.TriggerDetails as AppServiceTriggerDetails);
}
}
return Task.CompletedTask;
}
}
}

View File

@@ -10,6 +10,8 @@ using Microsoft.Extensions.DependencyInjection;
using Serilog; using Serilog;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.Core; using Windows.ApplicationModel.Core;
using Windows.Foundation.Metadata; using Windows.Foundation.Metadata;
using Windows.Storage; using Windows.Storage;
@@ -37,6 +39,7 @@ namespace Wino
public new static App Current => (App)Application.Current; public new static App Current => (App)Application.Current;
public IServiceProvider Services { get; } public IServiceProvider Services { get; }
private readonly IWinoServerConnectionManager<AppServiceConnection> _appServiceConnectionManager;
private readonly ILogInitializer _logInitializer; private readonly ILogInitializer _logInitializer;
private readonly IThemeService _themeService; private readonly IThemeService _themeService;
private readonly IDatabaseService _databaseService; private readonly IDatabaseService _databaseService;
@@ -47,8 +50,9 @@ namespace Wino
// Order matters. // Order matters.
private List<IInitializeAsync> initializeServices => new List<IInitializeAsync>() private List<IInitializeAsync> initializeServices => new List<IInitializeAsync>()
{ {
_translationService,
_databaseService, _databaseService,
_appServiceConnectionManager,
_translationService,
_themeService, _themeService,
_synchronizerFactory _synchronizerFactory
}; };
@@ -60,6 +64,7 @@ namespace Wino
UnhandledException += OnAppUnhandledException; UnhandledException += OnAppUnhandledException;
EnteredBackground += OnEnteredBackground; EnteredBackground += OnEnteredBackground;
LeavingBackground += OnLeavingBackground; LeavingBackground += OnLeavingBackground;
Suspending += OnSuspending;
Services = ConfigureServices(); Services = ConfigureServices();
@@ -70,6 +75,7 @@ namespace Wino
ConfigurePrelaunch(); ConfigurePrelaunch();
ConfigureXbox(); ConfigureXbox();
_appServiceConnectionManager = Services.GetService<IWinoServerConnectionManager<AppServiceConnection>>();
_themeService = Services.GetService<IThemeService>(); _themeService = Services.GetService<IThemeService>();
_databaseService = Services.GetService<IDatabaseService>(); _databaseService = Services.GetService<IDatabaseService>();
_appInitializerService = Services.GetService<IAppInitializerService>(); _appInitializerService = Services.GetService<IAppInitializerService>();
@@ -79,6 +85,12 @@ namespace Wino
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
} }
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 LogActivation(string log) => Log.Information($"{WinoLaunchLogPrefix}{log}");
private void OnLeavingBackground(object sender, LeavingBackgroundEventArgs e) => LogActivation($"Wino went foreground."); private void OnLeavingBackground(object sender, LeavingBackgroundEventArgs e) => LogActivation($"Wino went foreground.");
private void OnEnteredBackground(object sender, EnteredBackgroundEventArgs e) => LogActivation($"Wino went background."); private void OnEnteredBackground(object sender, EnteredBackgroundEventArgs e) => LogActivation($"Wino went background.");
@@ -101,7 +113,8 @@ namespace Wino
private void RegisterActivationHandlers(IServiceCollection services) private void RegisterActivationHandlers(IServiceCollection services)
{ {
services.AddTransient<ProtocolActivationHandler>(); services.AddTransient<ProtocolActivationHandler>();
services.AddTransient<BackgroundActivationHandler>(); services.AddTransient<BackgroundActivationHandlerEx>();
// services.AddTransient<BackgroundActivationHandler>();
services.AddTransient<ToastNotificationActivationHandler>(); services.AddTransient<ToastNotificationActivationHandler>();
services.AddTransient<FileActivationHandler>(); services.AddTransient<FileActivationHandler>();
} }
@@ -246,7 +259,10 @@ namespace Wino
private async Task ActivateWinoAsync(object args) private async Task ActivateWinoAsync(object args)
{ {
await PreInitializationAsync(); foreach (var service in initializeServices)
{
await service.InitializeAsync().ConfigureAwait(false);
}
if (IsInteractiveLaunchArgs(args)) if (IsInteractiveLaunchArgs(args))
{ {
@@ -270,37 +286,6 @@ namespace Wino
} }
} }
/// <summary>
/// Tasks that must run before the activation and launch.
/// Regardless of whether it's an interactive launch or not.
/// </summary>
private async Task PreInitializationAsync()
{
// Handle migrations.
// TODO: Automate migration process with more proper way.
if (!ApplicationData.Current.LocalSettings.Values.ContainsKey("Migration_169"))
{
try
{
await _appInitializerService.MigrateAsync();
}
catch (Exception ex)
{
Log.Error(ex, $"{WinoLaunchLogPrefix}Migration_169 failed.");
}
finally
{
ApplicationData.Current.LocalSettings.Values["Migration_169"] = true;
}
}
foreach (var service in initializeServices)
{
await service.InitializeAsync();
}
}
private async Task HandleActivationAsync(object activationArgs) private async Task HandleActivationAsync(object activationArgs)
{ {
var activationHandler = GetActivationHandlers().FirstOrDefault(h => h.CanHandle(activationArgs)); var activationHandler = GetActivationHandlers().FirstOrDefault(h => h.CanHandle(activationArgs));
@@ -323,9 +308,15 @@ namespace Wino
private IEnumerable<ActivationHandler> GetActivationHandlers() private IEnumerable<ActivationHandler> GetActivationHandlers()
{ {
yield return Services.GetService<ProtocolActivationHandler>(); yield return Services.GetService<ProtocolActivationHandler>();
yield return Services.GetService<BackgroundActivationHandler>(); yield return Services.GetService<BackgroundActivationHandlerEx>(); // New app service background task handler.
// yield return Services.GetService<BackgroundActivationHandler>(); // Old UWP background task handler.
yield return Services.GetService<ToastNotificationActivationHandler>(); yield return Services.GetService<ToastNotificationActivationHandler>();
yield return Services.GetService<FileActivationHandler>(); yield return Services.GetService<FileActivationHandler>();
} }
public void OnBackgroundTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
Log.Information($"Background task {sender.Task.Name} was canceled. Reason: {reason}");
}
} }
} }

View File

@@ -515,6 +515,14 @@
IsOpen="False" IsOpen="False"
PreferredPlacement="Bottom" PreferredPlacement="Bottom"
Target="{x:Bind ShellInfoBar}" /> Target="{x:Bind ShellInfoBar}" />
<Grid
Grid.Column="1"
Padding="14"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<TextBlock Text="{x:Bind ViewModel.ServerConnectionManager.Status, Mode=OneWay}" />
</Grid>
</Grid> </Grid>
</muxc:NavigationView> </muxc:NavigationView>

View File

@@ -92,13 +92,6 @@
Enabled="false" Enabled="false"
DisplayName="Wino Startup Service" /> DisplayName="Wino Startup Service" />
</uap5:Extension> </uap5:Extension>
<!-- Registration of full trust backend application. -->
<!--<uap:Extension Category="windows.appService">
<uap:AppService Name="Wino.AppService" />
</uap:Extension>-->
<!--<desktop:Extension Category="windows.fullTrustProcess" Executable="Wino.AppService.exe" />-->
</Extensions> </Extensions>
</Application> </Application>
</Applications> </Applications>

View File

@@ -15,12 +15,12 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Accounts;
using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Messages.Shell; using Wino.Core.Messages.Shell;
using Wino.Core.Messages.Synchronization; using Wino.Core.Messages.Synchronization;
using Wino.Core.UWP.Extensions; using Wino.Core.UWP.Extensions;
using Wino.Dialogs; using Wino.Dialogs;
using Wino.Messages.Server;
namespace Wino.Services namespace Wino.Services
{ {

View File

@@ -6,9 +6,9 @@ using MoreLinq;
using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Requests;
using Wino.Core.Messages.Navigation; using Wino.Core.Messages.Navigation;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
using Wino.Messages.Server;
using Wino.Views.Abstract; using Wino.Views.Abstract;
using Wino.Views.Account; using Wino.Views.Account;
using Wino.Views.Settings; using Wino.Views.Settings;

View File

@@ -229,6 +229,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Activation\ActivationHandler.cs" /> <Compile Include="Activation\ActivationHandler.cs" />
<Compile Include="Activation\BackgroundActivationHandler.cs" /> <Compile Include="Activation\BackgroundActivationHandler.cs" />
<Compile Include="Activation\BackgroundActivationHandlerEx.cs" />
<Compile Include="Activation\DefaultActivationHandler.cs" /> <Compile Include="Activation\DefaultActivationHandler.cs" />
<Compile Include="Activation\FileActivationHandler.cs" /> <Compile Include="Activation\FileActivationHandler.cs" />
<Compile Include="Activation\ProtocolActivationHandler.cs" /> <Compile Include="Activation\ProtocolActivationHandler.cs" />
@@ -770,7 +771,6 @@
<Content Include="Assets\Square44x44Logo.scale-200.png" /> <Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" /> <Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" /> <Content Include="Assets\Wide310x150Logo.scale-200.png" />
<None Include="Wino.Mail_TemporaryKey.pfx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Assets\Thumbnails\uber.com.png" /> <Content Include="Assets\Thumbnails\uber.com.png" />
@@ -812,7 +812,9 @@
<Name>Windows Desktop Extensions for the UWP</Name> <Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference> </SDKReference>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<Folder Include="Server\" />
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion> <VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,7 +1,7 @@
using System; using System;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
namespace Wino.Messages.Accounts namespace Wino.Messages.Client.Accounts
{ {
/// <summary> /// <summary>
/// When menu item for the account is requested to be extended. /// When menu item for the account is requested to be extended.

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Wino.Messages.Accounts namespace Wino.Messages.Client.Accounts
{ {
/// <summary> /// <summary>
/// Emitted when account menu items are reordered. /// Emitted when account menu items are reordered.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Accounts namespace Wino.Messages.Client.Accounts
{ {
/// <summary> /// <summary>
/// When a full menu refresh for accounts menu is requested. /// When a full menu refresh for accounts menu is requested.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Wino.Messages.Authorization namespace Wino.Messages.Client.Authorization
{ {
/// <summary> /// <summary>
/// When Google authentication makes a callback to the app via protocol activation to the app. /// When Google authentication makes a callback to the app via protocol activation to the app.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When rendered html is requested to cancel. /// When rendered html is requested to cancel.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When reset all mail selections requested. /// When reset all mail selections requested.

View File

@@ -1,6 +1,6 @@
using Wino.Core.Domain.Models.Reader; using Wino.Core.Domain.Models.Reader;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When a new composing requested. /// When a new composing requested.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When rendering frame should be disposed. /// When rendering frame should be disposed.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When existing a new html is requested to be rendered due to mail selection or signature. /// When existing a new html is requested to be rendered due to mail selection or signature.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When IMAP setup dialog requestes back breadcrumb navigation. /// When IMAP setup dialog requestes back breadcrumb navigation.

View File

@@ -1,6 +1,6 @@
using Wino.Core.Domain.Entities; using Wino.Core.Domain.Entities;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When user asked to dismiss IMAP setup dialog. /// When user asked to dismiss IMAP setup dialog.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When IMAP setup dialog breadcrumb navigation requested. /// When IMAP setup dialog breadcrumb navigation requested.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When a IMailItem needs to be navigated (or selected) /// When a IMailItem needs to be navigated (or selected)

View File

@@ -2,7 +2,7 @@
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// Selects the given FolderMenuItem in the shell folders list. /// Selects the given FolderMenuItem in the shell folders list.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
public record RefreshUnreadCountsMessage(Guid AccountId); public record RefreshUnreadCountsMessage(Guid AccountId);
} }

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When mail save as PDF requested. /// When mail save as PDF requested.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Mails namespace Wino.Messages.Client.Mails
{ {
/// <summary> /// <summary>
/// When selected mail count is changed. /// When selected mail count is changed.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Navigation namespace Wino.Messages.Client.Navigation
{ {
/// <summary> /// <summary>
/// When back navigation is requested for breadcrumb pages. /// When back navigation is requested for breadcrumb pages.

View File

@@ -1,6 +1,6 @@
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
namespace Wino.Messages.Navigation namespace Wino.Messages.Client.Navigation
{ {
/// <summary> /// <summary>
/// When Breadcrumb control navigation requested. /// When Breadcrumb control navigation requested.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Navigation namespace Wino.Messages.Client.Navigation
{ {
/// <summary> /// <summary>
/// Navigates to settings page. /// Navigates to settings page.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
/// <summary> /// <summary>
/// When the application theme changed. /// When the application theme changed.

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Wino.Core.Domain.Entities; using Wino.Core.Domain.Entities;
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
/// <summary> /// <summary>
/// When /// When

View File

@@ -1,7 +1,7 @@
using System; using System;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
/// <summary> /// <summary>
/// For displaying right sliding notification message in shell. /// For displaying right sliding notification message in shell.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
/// <summary> /// <summary>
/// When application language is updated. /// When application language is updated.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
public class MailtoProtocolMessageRequested { } public class MailtoProtocolMessageRequested { }
} }

View File

@@ -1,6 +1,6 @@
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
/// <summary> /// <summary>
/// When navigation pane mode is changed. /// When navigation pane mode is changed.

View File

@@ -1,4 +1,4 @@
namespace Wino.Messages.Shell namespace Wino.Messages.Client.Shell
{ {
/// <summary> /// <summary>
/// When reading mail state or reader pane narrowed state is changed. /// When reading mail state or reader pane narrowed state is changed.

View File

@@ -1,7 +1,7 @@
using System; using System;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
namespace Wino.Messages.Synchronization namespace Wino.Messages.Client.Synchronization
{ {
public record AccountSynchronizationCompleted(Guid AccountId, SynchronizationCompletedState Result, Guid? SynchronizationTrackingId); public record AccountSynchronizationCompleted(Guid AccountId, SynchronizationCompletedState Result, Guid? SynchronizationTrackingId);
} }

View File

@@ -1,7 +1,7 @@
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Synchronization namespace Wino.Messages.Client.Synchronization
{ {
/// <summary> /// <summary>
/// Emitted when synchronizer state is updated. /// Emitted when synchronizer state is updated.

View File

@@ -1,6 +1,6 @@
using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Domain.Models.Synchronization;
namespace Wino.Messages.Synchronization namespace Wino.Messages.Client.Synchronization
{ {
/// <summary> /// <summary>
/// Triggers a new synchronization if possible. /// Triggers a new synchronization if possible.

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record AccountCreatedMessage(MailAccount Account) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record AccountRemovedMessage(MailAccount Account) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record AccountUpdatedMessage(MailAccount Account) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record DraftCreated(MailCopy DraftMail, MailAccount Account) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record DraftFailed(MailCopy DraftMail, MailAccount Account) : IServerMessage;
}

View File

@@ -0,0 +1,6 @@
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record DraftMapped(string LocalDraftCopyId, string RemoteDraftCopyId) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders;
namespace Wino.Messages.Server
{
public record FolderRenamed(IMailItemFolder MailItemFolder) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders;
namespace Wino.Messages.Server
{
public record FolderSynchronizationEnabled(IMailItemFolder MailItemFolder) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record MailAddedMessage(MailCopy AddedMail) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record MailDownloadedMessage(MailCopy DownloadedMail) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record MailRemovedMessage(MailCopy RemovedMail) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record MailUpdatedMessage(MailCopy UpdatedMail) : IServerMessage;
}

View File

@@ -0,0 +1,7 @@
using System;
using Wino.Core.Domain.Interfaces;
namespace Wino.Messages.Server
{
public record MergedInboxRenamed(Guid MergedInboxId, string NewName) : IServerMessage;
}

View File

@@ -1,25 +0,0 @@
using System;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders;
namespace Wino.Core.Domain.Models.Requests
{
public record MailAddedMessage(MailCopy AddedMail) : IUIMessage;
public record MailRemovedMessage(MailCopy RemovedMail) : IUIMessage;
public record MailUpdatedMessage(MailCopy UpdatedMail) : IUIMessage;
public record MailDownloadedMessage(MailCopy DownloadedMail) : IUIMessage;
public record AccountCreatedMessage(MailAccount Account) : IUIMessage;
public record AccountRemovedMessage(MailAccount Account) : IUIMessage;
public record AccountUpdatedMessage(MailAccount Account) : IUIMessage;
public record DraftCreated(MailCopy DraftMail, MailAccount Account) : IUIMessage;
public record DraftFailed(MailCopy DraftMail, MailAccount Account) : IUIMessage;
public record DraftMapped(string LocalDraftCopyId, string RemoteDraftCopyId) : IUIMessage;
public record MergedInboxRenamed(Guid MergedInboxId, string NewName) : IUIMessage;
public record FolderRenamed(IMailItemFolder MailItemFolder) : IUIMessage;
public record FolderSynchronizationEnabled(IMailItemFolder MailItemFolder) : IUIMessage;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

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