Tracking failed imap setup steps for app insights.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using SQLite;
|
using SQLite;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
|
|
||||||
@@ -49,4 +50,25 @@ public class CustomServerInformation
|
|||||||
/// Default is 5.
|
/// Default is 5.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int MaxConcurrentClients { get; set; }
|
public int MaxConcurrentClients { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetConnectionProperties()
|
||||||
|
{
|
||||||
|
// Printout the public connection properties.
|
||||||
|
|
||||||
|
var connectionProperties = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "IncomingServer", IncomingServer },
|
||||||
|
{ "IncomingServerPort", IncomingServerPort },
|
||||||
|
{ "IncomingServerSocketOption", IncomingServerSocketOption.ToString() },
|
||||||
|
{ "IncomingAuthenticationMethod", IncomingAuthenticationMethod.ToString() },
|
||||||
|
{ "OutgoingServer", OutgoingServer },
|
||||||
|
{ "OutgoingServerPort", OutgoingServerPort },
|
||||||
|
{ "OutgoingServerSocketOption", OutgoingServerSocketOption.ToString() },
|
||||||
|
{ "OutgoingAuthenticationMethod", OutgoingAuthenticationMethod.ToString() },
|
||||||
|
{ "ProxyServer", ProxyServer },
|
||||||
|
{ "ProxyServerPort", ProxyServerPort }
|
||||||
|
};
|
||||||
|
|
||||||
|
return connectionProperties;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,30 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Wino.Core.Domain.Entities.Shared;
|
||||||
|
|
||||||
namespace Wino.Core.Domain.Exceptions;
|
namespace Wino.Core.Domain.Exceptions;
|
||||||
|
|
||||||
public class ImapClientPoolException : Exception
|
public class ImapClientPoolException : Exception
|
||||||
{
|
{
|
||||||
|
public ImapClientPoolException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImapClientPoolException(string message, CustomServerInformation customServerInformation, string protocolLog) : base(message)
|
||||||
|
{
|
||||||
|
CustomServerInformation = customServerInformation;
|
||||||
|
ProtocolLog = protocolLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImapClientPoolException(string message, string protocolLog) : base(message)
|
||||||
|
{
|
||||||
|
ProtocolLog = protocolLog;
|
||||||
|
}
|
||||||
|
|
||||||
public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException)
|
public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException)
|
||||||
{
|
{
|
||||||
ProtocolLog = protocolLog;
|
ProtocolLog = protocolLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CustomServerInformation CustomServerInformation { get; }
|
||||||
public string ProtocolLog { get; }
|
public string ProtocolLog { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Wino.Core.Domain.Interfaces;
|
|
||||||
|
|
||||||
public interface ILogInitializer
|
|
||||||
{
|
|
||||||
void SetupLogger(string fullLogFilePath);
|
|
||||||
|
|
||||||
void RefreshLoggingLevel();
|
|
||||||
}
|
|
||||||
10
Wino.Core.Domain/Interfaces/IWinoLogger.cs
Normal file
10
Wino.Core.Domain/Interfaces/IWinoLogger.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
|
public interface IWinoLogger
|
||||||
|
{
|
||||||
|
void SetupLogger(string fullLogFilePath);
|
||||||
|
void RefreshLoggingLevel();
|
||||||
|
void TrackEvent(string eventName, Dictionary<string, string> properties = null);
|
||||||
|
}
|
||||||
@@ -22,227 +22,228 @@ using Wino.Core.Domain;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.UWP;
|
namespace Wino.Core.UWP
|
||||||
|
|
||||||
public abstract class WinoApplication : Application
|
|
||||||
{
|
{
|
||||||
public new static WinoApplication Current => (WinoApplication)Application.Current;
|
public abstract class WinoApplication : Application
|
||||||
public const string WinoLaunchLogPrefix = "[Wino Launch] ";
|
|
||||||
|
|
||||||
public IServiceProvider Services { get; }
|
|
||||||
protected ILogInitializer LogInitializer { get; }
|
|
||||||
protected IApplicationConfiguration AppConfiguration { get; }
|
|
||||||
protected IWinoServerConnectionManager<AppServiceConnection> AppServiceConnectionManager { get; }
|
|
||||||
protected IThemeService ThemeService { get; }
|
|
||||||
protected IDatabaseService DatabaseService { get; }
|
|
||||||
protected ITranslationService TranslationService { get; }
|
|
||||||
|
|
||||||
protected WinoApplication()
|
|
||||||
{
|
{
|
||||||
ConfigurePrelaunch();
|
public new static WinoApplication Current => (WinoApplication)Application.Current;
|
||||||
|
public const string WinoLaunchLogPrefix = "[Wino Launch] ";
|
||||||
|
|
||||||
Services = ConfigureServices();
|
public IServiceProvider Services { get; }
|
||||||
|
protected IWinoLogger LogInitializer { get; }
|
||||||
|
protected IApplicationConfiguration AppConfiguration { get; }
|
||||||
|
protected IWinoServerConnectionManager<AppServiceConnection> AppServiceConnectionManager { get; }
|
||||||
|
protected IThemeService ThemeService { get; }
|
||||||
|
protected IDatabaseService DatabaseService { get; }
|
||||||
|
protected ITranslationService TranslationService { get; }
|
||||||
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
protected WinoApplication()
|
||||||
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
|
|
||||||
UnhandledException += OnAppUnhandledException;
|
|
||||||
|
|
||||||
Resuming += OnResuming;
|
|
||||||
Suspending += OnSuspending;
|
|
||||||
|
|
||||||
LogInitializer = Services.GetService<ILogInitializer>();
|
|
||||||
AppConfiguration = Services.GetService<IApplicationConfiguration>();
|
|
||||||
|
|
||||||
AppServiceConnectionManager = Services.GetService<IWinoServerConnectionManager<AppServiceConnection>>();
|
|
||||||
ThemeService = Services.GetService<IThemeService>();
|
|
||||||
DatabaseService = Services.GetService<IDatabaseService>();
|
|
||||||
TranslationService = Services.GetService<ITranslationService>();
|
|
||||||
|
|
||||||
// Make sure the paths are setup on app start.
|
|
||||||
AppConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;
|
|
||||||
AppConfiguration.PublisherSharedFolderPath = ApplicationData.Current.GetPublisherCacheFolder(ApplicationConfiguration.SharedFolderName).Path;
|
|
||||||
AppConfiguration.ApplicationTempFolderPath = ApplicationData.Current.TemporaryFolder.Path;
|
|
||||||
|
|
||||||
ConfigureLogging();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
|
|
||||||
=> Log.Fatal(e.ExceptionObject as Exception, "AppDomain Unhandled Exception");
|
|
||||||
|
|
||||||
private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
|
||||||
=> Log.Error(e.Exception, "Unobserved Task Exception");
|
|
||||||
|
|
||||||
private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
|
|
||||||
{
|
|
||||||
Log.Fatal(e.Exception, "Unhandled Exception");
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void OnApplicationCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e);
|
|
||||||
protected abstract IEnumerable<ActivationHandler> GetActivationHandlers();
|
|
||||||
protected abstract ActivationHandler<IActivatedEventArgs> GetDefaultActivationHandler();
|
|
||||||
protected override void OnWindowCreated(WindowCreatedEventArgs args)
|
|
||||||
{
|
|
||||||
base.OnWindowCreated(args);
|
|
||||||
|
|
||||||
ConfigureTitleBar();
|
|
||||||
|
|
||||||
LogActivation($"OnWindowCreated -> IsWindowNull: {args.Window == null}");
|
|
||||||
|
|
||||||
TryRegisterAppCloseChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<IInitializeAsync> GetActivationServices()
|
|
||||||
{
|
|
||||||
yield return DatabaseService;
|
|
||||||
yield return TranslationService;
|
|
||||||
yield return ThemeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task InitializeServicesAsync() => GetActivationServices().Select(a => a.InitializeAsync()).WhenAll();
|
|
||||||
|
|
||||||
public bool IsInteractiveLaunchArgs(object args) => args is IActivatedEventArgs;
|
|
||||||
|
|
||||||
public void LogActivation(string log) => Log.Information($"{WinoLaunchLogPrefix}{log}");
|
|
||||||
|
|
||||||
private void ConfigureTitleBar()
|
|
||||||
{
|
|
||||||
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
|
|
||||||
var applicationViewTitleBar = ApplicationView.GetForCurrentView().TitleBar;
|
|
||||||
|
|
||||||
// Extend shell content into core window to meet design requirements.
|
|
||||||
coreTitleBar.ExtendViewIntoTitleBar = true;
|
|
||||||
|
|
||||||
// Change system buttons and background colors to meet design requirements.
|
|
||||||
applicationViewTitleBar.ButtonBackgroundColor = Colors.Transparent;
|
|
||||||
applicationViewTitleBar.BackgroundColor = Colors.Transparent;
|
|
||||||
applicationViewTitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
|
||||||
applicationViewTitleBar.ButtonForegroundColor = Colors.White;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ActivateWinoAsync(object args)
|
|
||||||
{
|
|
||||||
await InitializeServicesAsync();
|
|
||||||
|
|
||||||
if (IsInteractiveLaunchArgs(args))
|
|
||||||
{
|
{
|
||||||
if (Window.Current.Content == null)
|
ConfigurePrelaunch();
|
||||||
|
|
||||||
|
Services = ConfigureServices();
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
|
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
|
||||||
|
UnhandledException += OnAppUnhandledException;
|
||||||
|
|
||||||
|
Resuming += OnResuming;
|
||||||
|
Suspending += OnSuspending;
|
||||||
|
|
||||||
|
LogInitializer = Services.GetService<IWinoLogger>();
|
||||||
|
AppConfiguration = Services.GetService<IApplicationConfiguration>();
|
||||||
|
|
||||||
|
AppServiceConnectionManager = Services.GetService<IWinoServerConnectionManager<AppServiceConnection>>();
|
||||||
|
ThemeService = Services.GetService<IThemeService>();
|
||||||
|
DatabaseService = Services.GetService<IDatabaseService>();
|
||||||
|
TranslationService = Services.GetService<ITranslationService>();
|
||||||
|
|
||||||
|
// Make sure the paths are setup on app start.
|
||||||
|
AppConfiguration.ApplicationDataFolderPath = ApplicationData.Current.LocalFolder.Path;
|
||||||
|
AppConfiguration.PublisherSharedFolderPath = ApplicationData.Current.GetPublisherCacheFolder(ApplicationConfiguration.SharedFolderName).Path;
|
||||||
|
AppConfiguration.ApplicationTempFolderPath = ApplicationData.Current.TemporaryFolder.Path;
|
||||||
|
|
||||||
|
ConfigureLogging();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
|
||||||
|
=> Log.Fatal(e.ExceptionObject as Exception, "AppDomain Unhandled Exception");
|
||||||
|
|
||||||
|
private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
||||||
|
=> Log.Error(e.Exception, "Unobserved Task Exception");
|
||||||
|
|
||||||
|
private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
Log.Fatal(e.Exception, "Unhandled Exception");
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void OnApplicationCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e);
|
||||||
|
protected abstract IEnumerable<ActivationHandler> GetActivationHandlers();
|
||||||
|
protected abstract ActivationHandler<IActivatedEventArgs> GetDefaultActivationHandler();
|
||||||
|
protected override void OnWindowCreated(WindowCreatedEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnWindowCreated(args);
|
||||||
|
|
||||||
|
ConfigureTitleBar();
|
||||||
|
|
||||||
|
LogActivation($"OnWindowCreated -> IsWindowNull: {args.Window == null}");
|
||||||
|
|
||||||
|
TryRegisterAppCloseChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IInitializeAsync> GetActivationServices()
|
||||||
|
{
|
||||||
|
yield return DatabaseService;
|
||||||
|
yield return TranslationService;
|
||||||
|
yield return ThemeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task InitializeServicesAsync() => GetActivationServices().Select(a => a.InitializeAsync()).WhenAll();
|
||||||
|
|
||||||
|
public bool IsInteractiveLaunchArgs(object args) => args is IActivatedEventArgs;
|
||||||
|
|
||||||
|
public void LogActivation(string log) => Log.Information($"{WinoLaunchLogPrefix}{log}");
|
||||||
|
|
||||||
|
private void ConfigureTitleBar()
|
||||||
|
{
|
||||||
|
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
|
||||||
|
var applicationViewTitleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||||
|
|
||||||
|
// Extend shell content into core window to meet design requirements.
|
||||||
|
coreTitleBar.ExtendViewIntoTitleBar = true;
|
||||||
|
|
||||||
|
// Change system buttons and background colors to meet design requirements.
|
||||||
|
applicationViewTitleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||||
|
applicationViewTitleBar.BackgroundColor = Colors.Transparent;
|
||||||
|
applicationViewTitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||||
|
applicationViewTitleBar.ButtonForegroundColor = Colors.White;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ActivateWinoAsync(object args)
|
||||||
|
{
|
||||||
|
await InitializeServicesAsync();
|
||||||
|
|
||||||
|
if (IsInteractiveLaunchArgs(args))
|
||||||
{
|
{
|
||||||
var mainFrame = new Frame();
|
if (Window.Current.Content == null)
|
||||||
|
{
|
||||||
|
var mainFrame = new Frame();
|
||||||
|
|
||||||
Window.Current.Content = mainFrame;
|
Window.Current.Content = mainFrame;
|
||||||
|
|
||||||
await ThemeService.InitializeAsync();
|
await ThemeService.InitializeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await HandleActivationAsync(args);
|
||||||
|
|
||||||
|
if (IsInteractiveLaunchArgs(args))
|
||||||
|
{
|
||||||
|
Window.Current.Activate();
|
||||||
|
|
||||||
|
LogActivation("Window activated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await HandleActivationAsync(args);
|
public async Task HandleActivationAsync(object activationArgs)
|
||||||
|
|
||||||
if (IsInteractiveLaunchArgs(args))
|
|
||||||
{
|
{
|
||||||
Window.Current.Activate();
|
if (GetActivationHandlers() != null)
|
||||||
|
|
||||||
LogActivation("Window activated");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task HandleActivationAsync(object activationArgs)
|
|
||||||
{
|
|
||||||
if (GetActivationHandlers() != null)
|
|
||||||
{
|
|
||||||
var activationHandler = GetActivationHandlers().FirstOrDefault(h => h.CanHandle(activationArgs)) ?? null;
|
|
||||||
|
|
||||||
if (activationHandler != null)
|
|
||||||
{
|
{
|
||||||
await activationHandler.HandleAsync(activationArgs);
|
var activationHandler = GetActivationHandlers().FirstOrDefault(h => h.CanHandle(activationArgs)) ?? null;
|
||||||
|
|
||||||
|
if (activationHandler != null)
|
||||||
|
{
|
||||||
|
await activationHandler.HandleAsync(activationArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsInteractiveLaunchArgs(activationArgs))
|
||||||
|
{
|
||||||
|
var defaultHandler = GetDefaultActivationHandler();
|
||||||
|
|
||||||
|
if (defaultHandler.CanHandle(activationArgs))
|
||||||
|
{
|
||||||
|
await defaultHandler.HandleAsync(activationArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsInteractiveLaunchArgs(activationArgs))
|
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
var defaultHandler = GetDefaultActivationHandler();
|
LogActivation($"OnLaunched -> {args.GetType().Name}, Kind -> {args.Kind}, PreviousExecutionState -> {args.PreviousExecutionState}, IsPrelaunch -> {args.PrelaunchActivated}");
|
||||||
|
|
||||||
if (defaultHandler.CanHandle(activationArgs))
|
if (!args.PrelaunchActivated)
|
||||||
{
|
{
|
||||||
await defaultHandler.HandleAsync(activationArgs);
|
await ActivateWinoAsync(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
protected override async void OnFileActivated(FileActivatedEventArgs args)
|
||||||
{
|
|
||||||
LogActivation($"OnLaunched -> {args.GetType().Name}, Kind -> {args.Kind}, PreviousExecutionState -> {args.PreviousExecutionState}, IsPrelaunch -> {args.PrelaunchActivated}");
|
|
||||||
|
|
||||||
if (!args.PrelaunchActivated)
|
|
||||||
{
|
{
|
||||||
|
base.OnFileActivated(args);
|
||||||
|
|
||||||
|
LogActivation($"OnFileActivated -> ItemCount: {args.Files.Count}, Kind: {args.Kind}, PreviousExecutionState: {args.PreviousExecutionState}");
|
||||||
|
|
||||||
await ActivateWinoAsync(args);
|
await ActivateWinoAsync(args);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override async void OnFileActivated(FileActivatedEventArgs args)
|
protected override async void OnActivated(IActivatedEventArgs args)
|
||||||
{
|
|
||||||
base.OnFileActivated(args);
|
|
||||||
|
|
||||||
LogActivation($"OnFileActivated -> ItemCount: {args.Files.Count}, Kind: {args.Kind}, PreviousExecutionState: {args.PreviousExecutionState}");
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TryRegisterAppCloseChange()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var systemNavigationManagerPreview = SystemNavigationManagerPreview.GetForCurrentView();
|
base.OnActivated(args);
|
||||||
|
|
||||||
systemNavigationManagerPreview.CloseRequested -= OnApplicationCloseRequested;
|
Log.Information($"OnActivated -> {args.GetType().Name}, Kind -> {args.Kind}, Prev Execution State -> {args.PreviousExecutionState}");
|
||||||
systemNavigationManagerPreview.CloseRequested += OnApplicationCloseRequested;
|
|
||||||
|
await ActivateWinoAsync(args);
|
||||||
}
|
}
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConfigurePrelaunch()
|
private void TryRegisterAppCloseChange()
|
||||||
{
|
|
||||||
if (ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch"))
|
|
||||||
CoreApplication.EnablePrelaunch(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual 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.
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
await AppServiceConnectionManager.ConnectAsync();
|
try
|
||||||
}
|
{
|
||||||
catch (OperationCanceledException)
|
var systemNavigationManagerPreview = SystemNavigationManagerPreview.GetForCurrentView();
|
||||||
{
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Failed to connect to server after resuming the app.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public virtual void OnSuspending(object sender, SuspendingEventArgs e) { }
|
|
||||||
|
|
||||||
public abstract IServiceProvider ConfigureServices();
|
systemNavigationManagerPreview.CloseRequested -= OnApplicationCloseRequested;
|
||||||
|
systemNavigationManagerPreview.CloseRequested += OnApplicationCloseRequested;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
public void ConfigureLogging()
|
private void ConfigurePrelaunch()
|
||||||
{
|
{
|
||||||
string logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ClientLogFile);
|
if (ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch"))
|
||||||
LogInitializer.SetupLogger(logFilePath);
|
CoreApplication.EnablePrelaunch(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public virtual 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.
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await AppServiceConnectionManager.ConnectAsync();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Failed to connect to server after resuming the app.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public virtual void OnSuspending(object sender, SuspendingEventArgs e) { }
|
||||||
|
|
||||||
|
public abstract IServiceProvider ConfigureServices();
|
||||||
|
|
||||||
|
public void ConfigureLogging()
|
||||||
|
{
|
||||||
|
string logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ClientLogFile);
|
||||||
|
LogInitializer.SetupLogger(logFilePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,124 +6,125 @@ using Wino.Core.Domain;
|
|||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.ViewModels;
|
namespace Wino.Core.ViewModels
|
||||||
|
|
||||||
public partial class AboutPageViewModel : CoreBaseViewModel
|
|
||||||
{
|
{
|
||||||
private readonly IStoreRatingService _storeRatingService;
|
public partial class AboutPageViewModel : CoreBaseViewModel
|
||||||
private readonly IMailDialogService _dialogService;
|
|
||||||
private readonly INativeAppService _nativeAppService;
|
|
||||||
private readonly IApplicationConfiguration _appInitializerService;
|
|
||||||
private readonly IClipboardService _clipboardService;
|
|
||||||
private readonly IFileService _fileService;
|
|
||||||
private readonly ILogInitializer _logInitializer;
|
|
||||||
|
|
||||||
public string VersionName => _nativeAppService.GetFullAppVersion();
|
|
||||||
public string DiscordChannelUrl => "https://discord.gg/windows-apps-hub-714581497222398064";
|
|
||||||
public string GitHubUrl => "https://github.com/bkaankose/Wino-Mail/";
|
|
||||||
public string PrivacyPolicyUrl => "https://www.winomail.app/support/privacy";
|
|
||||||
public string PaypalUrl => "https://paypal.me/bkaankose?country.x=PL&locale.x=en_US";
|
|
||||||
|
|
||||||
public IPreferencesService PreferencesService { get; }
|
|
||||||
|
|
||||||
public AboutPageViewModel(IStoreRatingService storeRatingService,
|
|
||||||
IMailDialogService dialogService,
|
|
||||||
INativeAppService nativeAppService,
|
|
||||||
IPreferencesService preferencesService,
|
|
||||||
IApplicationConfiguration appInitializerService,
|
|
||||||
IClipboardService clipboardService,
|
|
||||||
IFileService fileService,
|
|
||||||
ILogInitializer logInitializer)
|
|
||||||
{
|
{
|
||||||
_storeRatingService = storeRatingService;
|
private readonly IStoreRatingService _storeRatingService;
|
||||||
_dialogService = dialogService;
|
private readonly IMailDialogService _dialogService;
|
||||||
_nativeAppService = nativeAppService;
|
private readonly INativeAppService _nativeAppService;
|
||||||
_logInitializer = logInitializer;
|
private readonly IApplicationConfiguration _appInitializerService;
|
||||||
_appInitializerService = appInitializerService;
|
private readonly IClipboardService _clipboardService;
|
||||||
_clipboardService = clipboardService;
|
private readonly IFileService _fileService;
|
||||||
_fileService = fileService;
|
private readonly IWinoLogger _logInitializer;
|
||||||
|
|
||||||
PreferencesService = preferencesService;
|
public string VersionName => _nativeAppService.GetFullAppVersion();
|
||||||
}
|
public string DiscordChannelUrl => "https://discord.gg/windows-apps-hub-714581497222398064";
|
||||||
|
public string GitHubUrl => "https://github.com/bkaankose/Wino-Mail/";
|
||||||
|
public string PrivacyPolicyUrl => "https://www.winomail.app/support/privacy";
|
||||||
|
public string PaypalUrl => "https://paypal.me/bkaankose?country.x=PL&locale.x=en_US";
|
||||||
|
|
||||||
protected override void OnActivated()
|
public IPreferencesService PreferencesService { get; }
|
||||||
{
|
|
||||||
base.OnActivated();
|
|
||||||
|
|
||||||
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
public AboutPageViewModel(IStoreRatingService storeRatingService,
|
||||||
PreferencesService.PreferenceChanged += PreferencesChanged;
|
IMailDialogService dialogService,
|
||||||
}
|
INativeAppService nativeAppService,
|
||||||
|
IPreferencesService preferencesService,
|
||||||
protected override void OnDeactivated()
|
IApplicationConfiguration appInitializerService,
|
||||||
{
|
IClipboardService clipboardService,
|
||||||
base.OnDeactivated();
|
IFileService fileService,
|
||||||
|
IWinoLogger logInitializer)
|
||||||
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PreferencesChanged(object sender, string e)
|
|
||||||
{
|
|
||||||
if (e == nameof(PreferencesService.IsLoggingEnabled))
|
|
||||||
{
|
{
|
||||||
_logInitializer.RefreshLoggingLevel();
|
_storeRatingService = storeRatingService;
|
||||||
|
_dialogService = dialogService;
|
||||||
|
_nativeAppService = nativeAppService;
|
||||||
|
_logInitializer = logInitializer;
|
||||||
|
_appInitializerService = appInitializerService;
|
||||||
|
_clipboardService = clipboardService;
|
||||||
|
_fileService = fileService;
|
||||||
|
|
||||||
|
PreferencesService = preferencesService;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
protected override void OnActivated()
|
||||||
private async Task CopyDiagnosticId()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
await _clipboardService.CopyClipboardAsync(PreferencesService.DiagnosticId);
|
base.OnActivated();
|
||||||
_dialogService.InfoBarMessage(Translator.Buttons_Copy, string.Format(Translator.ClipboardTextCopied_Message, "Id"), InfoBarMessageType.Success);
|
|
||||||
|
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
||||||
|
PreferencesService.PreferenceChanged += PreferencesChanged;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
protected override void OnDeactivated()
|
||||||
{
|
{
|
||||||
_dialogService.InfoBarMessage(Translator.GeneralTitle_Error, string.Format(Translator.ClipboardTextCopyFailed_Message, "Id"), InfoBarMessageType.Error);
|
base.OnDeactivated();
|
||||||
Log.Error(ex, "Failed to copy diagnostic id to clipboard.");
|
|
||||||
|
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
private void PreferencesChanged(object sender, string e)
|
||||||
private async Task ShareWinoLogAsync()
|
|
||||||
{
|
|
||||||
var appDataFolder = _appInitializerService.ApplicationDataFolderPath;
|
|
||||||
|
|
||||||
var selectedFolderPath = await _dialogService.PickWindowsFolderAsync();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(selectedFolderPath)) return;
|
|
||||||
|
|
||||||
var areLogsSaved = await _fileService.SaveLogsToFolderAsync(appDataFolder, selectedFolderPath).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (areLogsSaved)
|
|
||||||
{
|
{
|
||||||
_dialogService.InfoBarMessage(Translator.Info_LogsSavedTitle, string.Format(Translator.Info_LogsSavedMessage, Constants.LogArchiveFileName), InfoBarMessageType.Success);
|
if (e == nameof(PreferencesService.IsLoggingEnabled))
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_dialogService.InfoBarMessage(Translator.Info_LogsNotFoundTitle, Translator.Info_LogsNotFoundMessage, InfoBarMessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private async Task Navigate(object url)
|
|
||||||
{
|
|
||||||
if (url is string stringUrl)
|
|
||||||
{
|
|
||||||
if (stringUrl == "Store")
|
|
||||||
await ShowRateDialogAsync();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Discord disclaimer message about server.
|
_logInitializer.RefreshLoggingLevel();
|
||||||
if (stringUrl == DiscordChannelUrl)
|
|
||||||
await _dialogService.ShowMessageAsync(Translator.DiscordChannelDisclaimerMessage,
|
|
||||||
Translator.DiscordChannelDisclaimerTitle,
|
|
||||||
WinoCustomMessageDialogIcon.Warning);
|
|
||||||
|
|
||||||
await _nativeAppService.LaunchUriAsync(new Uri(stringUrl));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Task ShowRateDialogAsync() => _storeRatingService.LaunchStorePageForReviewAsync();
|
[RelayCommand]
|
||||||
|
private async Task CopyDiagnosticId()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _clipboardService.CopyClipboardAsync(PreferencesService.DiagnosticId);
|
||||||
|
_dialogService.InfoBarMessage(Translator.Buttons_Copy, string.Format(Translator.ClipboardTextCopied_Message, "Id"), InfoBarMessageType.Success);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_dialogService.InfoBarMessage(Translator.GeneralTitle_Error, string.Format(Translator.ClipboardTextCopyFailed_Message, "Id"), InfoBarMessageType.Error);
|
||||||
|
Log.Error(ex, "Failed to copy diagnostic id to clipboard.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task ShareWinoLogAsync()
|
||||||
|
{
|
||||||
|
var appDataFolder = _appInitializerService.ApplicationDataFolderPath;
|
||||||
|
|
||||||
|
var selectedFolderPath = await _dialogService.PickWindowsFolderAsync();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(selectedFolderPath)) return;
|
||||||
|
|
||||||
|
var areLogsSaved = await _fileService.SaveLogsToFolderAsync(appDataFolder, selectedFolderPath).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (areLogsSaved)
|
||||||
|
{
|
||||||
|
_dialogService.InfoBarMessage(Translator.Info_LogsSavedTitle, string.Format(Translator.Info_LogsSavedMessage, Constants.LogArchiveFileName), InfoBarMessageType.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_dialogService.InfoBarMessage(Translator.Info_LogsNotFoundTitle, Translator.Info_LogsNotFoundMessage, InfoBarMessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task Navigate(object url)
|
||||||
|
{
|
||||||
|
if (url is string stringUrl)
|
||||||
|
{
|
||||||
|
if (stringUrl == "Store")
|
||||||
|
await ShowRateDialogAsync();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Discord disclaimer message about server.
|
||||||
|
if (stringUrl == DiscordChannelUrl)
|
||||||
|
await _dialogService.ShowMessageAsync(Translator.DiscordChannelDisclaimerMessage,
|
||||||
|
Translator.DiscordChannelDisclaimerTitle,
|
||||||
|
WinoCustomMessageDialogIcon.Warning);
|
||||||
|
|
||||||
|
await _nativeAppService.LaunchUriAsync(new Uri(stringUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task ShowRateDialogAsync() => _storeRatingService.LaunchStorePageForReviewAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MailKit.Net.Smtp;
|
||||||
using Wino.Core.Domain.Entities.Shared;
|
using Wino.Core.Domain.Entities.Shared;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Connectivity;
|
using Wino.Core.Domain.Models.Connectivity;
|
||||||
@@ -53,5 +54,14 @@ public class ImapTestService : IImapTestService
|
|||||||
|
|
||||||
clientPool.Release(client);
|
clientPool.Release(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test SMTP connectivity.
|
||||||
|
using var smtpClient = new SmtpClient();
|
||||||
|
|
||||||
|
if (!smtpClient.IsConnected)
|
||||||
|
await smtpClient.ConnectAsync(serverInformation.OutgoingServer, int.Parse(serverInformation.OutgoingServerPort), MailKit.Security.SecureSocketOptions.Auto);
|
||||||
|
|
||||||
|
if (!smtpClient.IsAuthenticated)
|
||||||
|
await smtpClient.AuthenticateAsync(serverInformation.OutgoingServerUsername, serverInformation.OutgoingServerPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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.Authentication;
|
using Wino.Core.Domain.Models.Authentication;
|
||||||
|
using Wino.Core.Domain.Models.Connectivity;
|
||||||
using Wino.Core.Domain.Models.Navigation;
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
using Wino.Core.Domain.Models.Synchronization;
|
using Wino.Core.Domain.Models.Synchronization;
|
||||||
using Wino.Core.ViewModels;
|
using Wino.Core.ViewModels;
|
||||||
@@ -28,6 +29,7 @@ public partial class AccountManagementViewModel : AccountManagementPageViewModel
|
|||||||
{
|
{
|
||||||
private readonly ISpecialImapProviderConfigResolver _specialImapProviderConfigResolver;
|
private readonly ISpecialImapProviderConfigResolver _specialImapProviderConfigResolver;
|
||||||
private readonly IImapTestService _imapTestService;
|
private readonly IImapTestService _imapTestService;
|
||||||
|
private readonly IWinoLogger _winoLogger;
|
||||||
|
|
||||||
public IMailDialogService MailDialogService { get; }
|
public IMailDialogService MailDialogService { get; }
|
||||||
|
|
||||||
@@ -39,12 +41,14 @@ public partial class AccountManagementViewModel : AccountManagementPageViewModel
|
|||||||
IProviderService providerService,
|
IProviderService providerService,
|
||||||
IImapTestService imapTestService,
|
IImapTestService imapTestService,
|
||||||
IStoreManagementService storeManagementService,
|
IStoreManagementService storeManagementService,
|
||||||
|
IWinoLogger winoLogger,
|
||||||
IAuthenticationProvider authenticationProvider,
|
IAuthenticationProvider authenticationProvider,
|
||||||
IPreferencesService preferencesService) : base(dialogService, winoServerConnectionManager, navigationService, accountService, providerService, storeManagementService, authenticationProvider, preferencesService)
|
IPreferencesService preferencesService) : base(dialogService, winoServerConnectionManager, navigationService, accountService, providerService, storeManagementService, authenticationProvider, preferencesService)
|
||||||
{
|
{
|
||||||
MailDialogService = dialogService;
|
MailDialogService = dialogService;
|
||||||
_specialImapProviderConfigResolver = specialImapProviderConfigResolver;
|
_specialImapProviderConfigResolver = specialImapProviderConfigResolver;
|
||||||
_imapTestService = imapTestService;
|
_imapTestService = imapTestService;
|
||||||
|
_winoLogger = winoLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
@@ -111,6 +115,7 @@ public partial class AccountManagementViewModel : AccountManagementPageViewModel
|
|||||||
};
|
};
|
||||||
|
|
||||||
await creationDialog.ShowDialogAsync(accountCreationCancellationTokenSource);
|
await creationDialog.ShowDialogAsync(accountCreationCancellationTokenSource);
|
||||||
|
|
||||||
creationDialog.State = AccountCreationDialogState.SigningIn;
|
creationDialog.State = AccountCreationDialogState.SigningIn;
|
||||||
|
|
||||||
string tokenInformation = string.Empty;
|
string tokenInformation = string.Empty;
|
||||||
@@ -146,7 +151,18 @@ public partial class AccountManagementViewModel : AccountManagementPageViewModel
|
|||||||
createdAccount.SenderName = accountCreationDialogResult.SpecialImapProviderDetails.SenderName;
|
createdAccount.SenderName = accountCreationDialogResult.SpecialImapProviderDetails.SenderName;
|
||||||
createdAccount.Address = customServerInformation.Address;
|
createdAccount.Address = customServerInformation.Address;
|
||||||
|
|
||||||
await _imapTestService.TestImapConnectionAsync(customServerInformation, true);
|
// Let server validate the imap/smtp connection.
|
||||||
|
var testResultResponse = await WinoServerConnectionManager.GetResponseAsync<ImapConnectivityTestResults, ImapConnectivityTestRequested>(new ImapConnectivityTestRequested(customServerInformation, true));
|
||||||
|
|
||||||
|
if (!testResultResponse.IsSuccess)
|
||||||
|
{
|
||||||
|
throw new Exception($"{Translator.IMAPSetupDialog_ConnectionFailedTitle}\n{testResultResponse.Message}");
|
||||||
|
}
|
||||||
|
else if (!testResultResponse.Data.IsSuccess)
|
||||||
|
{
|
||||||
|
// Server connectivity might succeed, but result might be failed.
|
||||||
|
throw new ImapClientPoolException(testResultResponse.Data.FailedReason, customServerInformation, testResultResponse.Data.FailureProtocolLog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -266,7 +282,18 @@ public partial class AccountManagementViewModel : AccountManagementPageViewModel
|
|||||||
{
|
{
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
catch (ImapClientPoolException clientPoolException)
|
catch (ImapClientPoolException testClientPoolException) when (testClientPoolException.CustomServerInformation != null)
|
||||||
|
{
|
||||||
|
var properties = testClientPoolException.CustomServerInformation.GetConnectionProperties();
|
||||||
|
|
||||||
|
properties.Add("ProtocolLog", testClientPoolException.ProtocolLog);
|
||||||
|
properties.Add("DiagnosticId", PreferencesService.DiagnosticId);
|
||||||
|
|
||||||
|
_winoLogger.TrackEvent("IMAP Test Failed", properties);
|
||||||
|
|
||||||
|
DialogService.InfoBarMessage(Translator.Info_AccountCreationFailedTitle, testClientPoolException.Message, InfoBarMessageType.Error);
|
||||||
|
}
|
||||||
|
catch (ImapClientPoolException clientPoolException) when (clientPoolException.InnerException != null)
|
||||||
{
|
{
|
||||||
DialogService.InfoBarMessage(Translator.Info_AccountCreationFailedTitle, clientPoolException.InnerException.Message, InfoBarMessageType.Error);
|
DialogService.InfoBarMessage(Translator.Info_AccountCreationFailedTitle, clientPoolException.InnerException.Message, InfoBarMessageType.Error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public partial class App : Application
|
|||||||
applicationFolderConfiguration.ApplicationTempFolderPath = ApplicationData.Current.TemporaryFolder.Path;
|
applicationFolderConfiguration.ApplicationTempFolderPath = ApplicationData.Current.TemporaryFolder.Path;
|
||||||
|
|
||||||
// Setup logger
|
// Setup logger
|
||||||
var logInitializer = Services.GetService<ILogInitializer>();
|
var logInitializer = Services.GetService<IWinoLogger>();
|
||||||
var logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ServerLogFile);
|
var logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ServerLogFile);
|
||||||
|
|
||||||
logInitializer.SetupLogger(logFilePath);
|
logInitializer.SetupLogger(logFilePath);
|
||||||
|
|||||||
@@ -2,34 +2,35 @@
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Services.Threading;
|
using Wino.Services.Threading;
|
||||||
|
|
||||||
namespace Wino.Services;
|
namespace Wino.Services
|
||||||
|
|
||||||
public static class ServicesContainerSetup
|
|
||||||
{
|
{
|
||||||
public static void RegisterSharedServices(this IServiceCollection services)
|
public static class ServicesContainerSetup
|
||||||
{
|
{
|
||||||
services.AddSingleton<ITranslationService, TranslationService>();
|
public static void RegisterSharedServices(this IServiceCollection services)
|
||||||
services.AddSingleton<IDatabaseService, DatabaseService>();
|
{
|
||||||
|
services.AddSingleton<ITranslationService, TranslationService>();
|
||||||
|
services.AddSingleton<IDatabaseService, DatabaseService>();
|
||||||
|
|
||||||
services.AddSingleton<IApplicationConfiguration, ApplicationConfiguration>();
|
services.AddSingleton<IApplicationConfiguration, ApplicationConfiguration>();
|
||||||
services.AddSingleton<ILogInitializer, LogInitializer>();
|
services.AddSingleton<IWinoLogger, WinoLogger>();
|
||||||
services.AddSingleton<ILaunchProtocolService, LaunchProtocolService>();
|
services.AddSingleton<ILaunchProtocolService, LaunchProtocolService>();
|
||||||
services.AddSingleton<IMimeFileService, MimeFileService>();
|
services.AddSingleton<IMimeFileService, MimeFileService>();
|
||||||
|
|
||||||
services.AddTransient<ICalendarService, CalendarService>();
|
services.AddTransient<ICalendarService, CalendarService>();
|
||||||
services.AddTransient<IMailService, MailService>();
|
services.AddTransient<IMailService, MailService>();
|
||||||
services.AddTransient<IFolderService, FolderService>();
|
services.AddTransient<IFolderService, FolderService>();
|
||||||
services.AddTransient<IAccountService, AccountService>();
|
services.AddTransient<IAccountService, AccountService>();
|
||||||
services.AddTransient<IContactService, ContactService>();
|
services.AddTransient<IContactService, ContactService>();
|
||||||
services.AddTransient<ISignatureService, SignatureService>();
|
services.AddTransient<ISignatureService, SignatureService>();
|
||||||
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
||||||
services.AddTransient<ISpecialImapProviderConfigResolver, SpecialImapProviderConfigResolver>();
|
services.AddTransient<ISpecialImapProviderConfigResolver, SpecialImapProviderConfigResolver>();
|
||||||
|
|
||||||
services.AddSingleton<IThreadingStrategyProvider, ThreadingStrategyProvider>();
|
services.AddSingleton<IThreadingStrategyProvider, ThreadingStrategyProvider>();
|
||||||
services.AddTransient<IOutlookThreadingStrategy, OutlookThreadingStrategy>();
|
services.AddTransient<IOutlookThreadingStrategy, OutlookThreadingStrategy>();
|
||||||
services.AddTransient<IGmailThreadingStrategy, GmailThreadingStrategy>();
|
services.AddTransient<IGmailThreadingStrategy, GmailThreadingStrategy>();
|
||||||
services.AddTransient<IImapThreadingStrategy, ImapThreadingStrategy>();
|
services.AddTransient<IImapThreadingStrategy, ImapThreadingStrategy>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Microsoft.ApplicationInsights.Extensibility;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.ApplicationInsights;
|
||||||
|
using Microsoft.ApplicationInsights.Extensibility;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Core;
|
using Serilog.Core;
|
||||||
using Serilog.Exceptions;
|
using Serilog.Exceptions;
|
||||||
@@ -7,20 +9,21 @@ using Wino.Services.Misc;
|
|||||||
|
|
||||||
namespace Wino.Services;
|
namespace Wino.Services;
|
||||||
|
|
||||||
public class LogInitializer : ILogInitializer
|
public class WinoLogger : IWinoLogger
|
||||||
{
|
{
|
||||||
private readonly LoggingLevelSwitch _levelSwitch = new LoggingLevelSwitch();
|
private readonly LoggingLevelSwitch _levelSwitch = new LoggingLevelSwitch();
|
||||||
private readonly IPreferencesService _preferencesService;
|
private readonly IPreferencesService _preferencesService;
|
||||||
private readonly IApplicationConfiguration _applicationConfiguration;
|
|
||||||
private readonly TelemetryConfiguration _telemetryConfiguration;
|
private readonly TelemetryConfiguration _telemetryConfiguration;
|
||||||
|
|
||||||
public LogInitializer(IPreferencesService preferencesService, IApplicationConfiguration applicationConfiguration)
|
public TelemetryClient TelemetryClient { get; private set; }
|
||||||
|
|
||||||
|
public WinoLogger(IPreferencesService preferencesService, IApplicationConfiguration applicationConfiguration)
|
||||||
{
|
{
|
||||||
_preferencesService = preferencesService;
|
_preferencesService = preferencesService;
|
||||||
_applicationConfiguration = applicationConfiguration;
|
|
||||||
|
|
||||||
_telemetryConfiguration = new TelemetryConfiguration(applicationConfiguration.ApplicationInsightsInstrumentationKey);
|
_telemetryConfiguration = new TelemetryConfiguration(applicationConfiguration.ApplicationInsightsInstrumentationKey);
|
||||||
|
|
||||||
|
TelemetryClient = new TelemetryClient(_telemetryConfiguration);
|
||||||
|
|
||||||
RefreshLoggingLevel();
|
RefreshLoggingLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +44,16 @@ public class LogInitializer : ILogInitializer
|
|||||||
.MinimumLevel.ControlledBy(_levelSwitch)
|
.MinimumLevel.ControlledBy(_levelSwitch)
|
||||||
.WriteTo.File(fullLogFilePath, retainedFileCountLimit: 3, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day)
|
.WriteTo.File(fullLogFilePath, retainedFileCountLimit: 3, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day)
|
||||||
.WriteTo.Debug()
|
.WriteTo.Debug()
|
||||||
.WriteTo.ApplicationInsights(_telemetryConfiguration, insightsTelemetryConverter, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error)
|
.WriteTo.ApplicationInsights(TelemetryClient, insightsTelemetryConverter, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error)
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.Enrich.WithExceptionDetails()
|
.Enrich.WithExceptionDetails()
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TrackEvent(string eventName, Dictionary<string, string> properties = null)
|
||||||
|
{
|
||||||
|
if (TelemetryClient == null) return;
|
||||||
|
|
||||||
|
TelemetryClient.TrackEvent(eventName, properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user