mirror of
https://github.com/cyanfish/naps2.git
synced 2024-09-11 15:26:55 +03:00
Refactor email provider display logic
This commit is contained in:
parent
1a20fdcebd
commit
f0cb9481b0
@ -2,113 +2,16 @@ using Eto.Drawing;
|
|||||||
using Eto.Forms;
|
using Eto.Forms;
|
||||||
using NAPS2.EtoForms.Layout;
|
using NAPS2.EtoForms.Layout;
|
||||||
using NAPS2.ImportExport.Email;
|
using NAPS2.ImportExport.Email;
|
||||||
using NAPS2.ImportExport.Email.Mapi;
|
|
||||||
using NAPS2.ImportExport.Email.Oauth;
|
|
||||||
using NAPS2.Scan;
|
|
||||||
|
|
||||||
namespace NAPS2.EtoForms.Ui;
|
namespace NAPS2.EtoForms.Ui;
|
||||||
|
|
||||||
public class EmailProviderForm : EtoDialogBase
|
public class EmailProviderForm : EtoDialogBase
|
||||||
{
|
{
|
||||||
private readonly SystemEmailClients _systemEmailClients;
|
private readonly EmailProviderController _controller;
|
||||||
private readonly GmailOauthProvider _gmailOauthProvider;
|
|
||||||
private readonly OutlookWebOauthProvider _outlookWebOauthProvider;
|
|
||||||
private readonly ThunderbirdEmailProvider _thunderbirdProvider;
|
|
||||||
|
|
||||||
private readonly List<EmailProviderWidget> _providerWidgets;
|
public EmailProviderForm(Naps2Config config, EmailProviderController controller) : base(config)
|
||||||
private readonly string[] _systemClientNames;
|
|
||||||
private readonly string? _defaultSystemClientName;
|
|
||||||
|
|
||||||
public EmailProviderForm(Naps2Config config, SystemEmailClients systemEmailClients,
|
|
||||||
GmailOauthProvider gmailOauthProvider, OutlookWebOauthProvider outlookWebOauthProvider,
|
|
||||||
ThunderbirdEmailProvider thunderbirdProvider) : base(config)
|
|
||||||
{
|
{
|
||||||
_systemEmailClients = systemEmailClients;
|
_controller = controller;
|
||||||
_gmailOauthProvider = gmailOauthProvider;
|
|
||||||
_outlookWebOauthProvider = outlookWebOauthProvider;
|
|
||||||
_thunderbirdProvider = thunderbirdProvider;
|
|
||||||
|
|
||||||
_providerWidgets = new List<EmailProviderWidget>();
|
|
||||||
#if NET6_0_OR_GREATER
|
|
||||||
if (!OperatingSystem.IsWindowsVersionAtLeast(7))
|
|
||||||
{
|
|
||||||
_systemClientNames = Array.Empty<string>();
|
|
||||||
_defaultSystemClientName = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
_systemClientNames = _systemEmailClients.GetNames();
|
|
||||||
_defaultSystemClientName = _systemEmailClients.GetDefaultName();
|
|
||||||
|
|
||||||
foreach (var clientName in _systemClientNames.OrderBy(x => x == _defaultSystemClientName ? 0 : 1))
|
|
||||||
{
|
|
||||||
var exePath = _systemEmailClients.GetExePath(clientName);
|
|
||||||
var icon = exePath == null ? null : EtoPlatform.Current.ExtractAssociatedIcon(exePath);
|
|
||||||
_providerWidgets.Add(new EmailProviderWidget
|
|
||||||
{
|
|
||||||
ProviderType = EmailProviderType.System,
|
|
||||||
ProviderIcon = icon ?? Icons.mail_yellow.ToEtoImage(),
|
|
||||||
ProviderName = clientName,
|
|
||||||
ClickAction = () => ChooseSystem(clientName)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#if NET6_0_OR_GREATER
|
|
||||||
}
|
|
||||||
|
|
||||||
// For Windows we expect Thunderbird to be used through MAPI. For Linux we need to handle it specially.
|
|
||||||
if (!OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
_providerWidgets.Add(new EmailProviderWidget
|
|
||||||
{
|
|
||||||
ProviderType = EmailProviderType.Thunderbird,
|
|
||||||
ProviderIcon = Icons.thunderbird.ToEtoImage(),
|
|
||||||
ProviderName = EmailProviderType.Thunderbird.Description(),
|
|
||||||
ClickAction = ChooseThunderbird,
|
|
||||||
// When Thunderbird isn't available, we disable it rather than hide it.
|
|
||||||
// The point is to give a hint to the user that Thunderbird support is present.
|
|
||||||
Enabled = _thunderbirdProvider.IsAvailable
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_gmailOauthProvider.HasClientCreds)
|
|
||||||
{
|
|
||||||
_providerWidgets.Add(new EmailProviderWidget
|
|
||||||
{
|
|
||||||
ProviderType = EmailProviderType.Gmail,
|
|
||||||
ProviderIcon = Icons.gmail.ToEtoImage(),
|
|
||||||
ProviderName = EmailProviderType.Gmail.Description(),
|
|
||||||
ClickAction = () => ChooseOauth(_gmailOauthProvider)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_outlookWebOauthProvider.HasClientCreds)
|
|
||||||
{
|
|
||||||
_providerWidgets.Add(new EmailProviderWidget
|
|
||||||
{
|
|
||||||
ProviderType = EmailProviderType.OutlookWeb,
|
|
||||||
ProviderIcon = Icons.outlookweb.ToEtoImage(),
|
|
||||||
ProviderName = EmailProviderType.OutlookWeb.Description(),
|
|
||||||
ClickAction = () => ChooseOauth(_outlookWebOauthProvider)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//providerWidgets.Add(new EmailProviderWidget
|
|
||||||
//{
|
|
||||||
// ProviderType = EmailProviderType.CustomSmtp,
|
|
||||||
// ProviderIcon = Icons.email_setting,
|
|
||||||
// ProviderName = EmailProviderType.CustomSmtp.Description(),
|
|
||||||
// ClickAction = ChooseCustomSmtp
|
|
||||||
//});
|
|
||||||
|
|
||||||
// Put the configured provider at the top
|
|
||||||
var defaultWidget = GetDefaultWidget();
|
|
||||||
if (defaultWidget != null)
|
|
||||||
{
|
|
||||||
_providerWidgets.Remove(defaultWidget);
|
|
||||||
_providerWidgets.Insert(0, defaultWidget);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void BuildLayout()
|
protected override void BuildLayout()
|
||||||
@ -120,7 +23,14 @@ public class EmailProviderForm : EtoDialogBase
|
|||||||
|
|
||||||
LayoutController.DefaultSpacing = 0;
|
LayoutController.DefaultSpacing = 0;
|
||||||
LayoutController.Content = L.Column(
|
LayoutController.Content = L.Column(
|
||||||
_providerWidgets.Select(x => C.Button(new ActionCommand(x.ClickAction)
|
_controller.GetWidgets().Select(x => C.Button(new ActionCommand(() =>
|
||||||
|
{
|
||||||
|
if (x.Choose())
|
||||||
|
{
|
||||||
|
Result = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
})
|
||||||
{
|
{
|
||||||
Text = x.ProviderName,
|
Text = x.ProviderName,
|
||||||
Image = x.ProviderIcon,
|
Image = x.ProviderIcon,
|
||||||
@ -131,71 +41,4 @@ public class EmailProviderForm : EtoDialogBase
|
|||||||
|
|
||||||
public bool Result { get; private set; }
|
public bool Result { get; private set; }
|
||||||
|
|
||||||
private void ChooseSystem(string clientName)
|
|
||||||
{
|
|
||||||
var transact = Config.User.BeginTransaction();
|
|
||||||
transact.Remove(c => c.EmailSetup);
|
|
||||||
transact.Set(c => c.EmailSetup.SystemProviderName, clientName);
|
|
||||||
transact.Set(c => c.EmailSetup.ProviderType, EmailProviderType.System);
|
|
||||||
transact.Commit();
|
|
||||||
Result = true;
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChooseThunderbird()
|
|
||||||
{
|
|
||||||
var transact = Config.User.BeginTransaction();
|
|
||||||
transact.Remove(c => c.EmailSetup);
|
|
||||||
transact.Set(c => c.EmailSetup.ProviderType, EmailProviderType.Thunderbird);
|
|
||||||
transact.Commit();
|
|
||||||
Result = true;
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChooseOauth(OauthProvider provider)
|
|
||||||
{
|
|
||||||
var authForm = FormFactory.Create<AuthorizeForm>();
|
|
||||||
authForm.OauthProvider = provider;
|
|
||||||
authForm.ShowModal();
|
|
||||||
if (authForm.Result)
|
|
||||||
{
|
|
||||||
Result = true;
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private EmailProviderWidget? GetDefaultWidget()
|
|
||||||
{
|
|
||||||
var emailSetup = Config.Get(c => c.EmailSetup);
|
|
||||||
foreach (var widget in _providerWidgets)
|
|
||||||
{
|
|
||||||
if (widget.ProviderType == emailSetup.ProviderType)
|
|
||||||
{
|
|
||||||
if (widget.ProviderType == EmailProviderType.System)
|
|
||||||
{
|
|
||||||
// System providers need additional logic since there may be more than one
|
|
||||||
if (widget.ProviderName == emailSetup.SystemProviderName
|
|
||||||
|| string.IsNullOrEmpty(emailSetup.SystemProviderName) &&
|
|
||||||
widget.ProviderName == _defaultSystemClientName)
|
|
||||||
{
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EmailProviderWidget
|
|
||||||
{
|
|
||||||
public required EmailProviderType ProviderType { get; init; }
|
|
||||||
public required Bitmap ProviderIcon { get; init; }
|
|
||||||
public required string ProviderName { get; init; }
|
|
||||||
public required Action ClickAction { get; init; }
|
|
||||||
public bool Enabled { get; set; } = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
155
NAPS2.Lib/ImportExport/Email/EmailProviderController.cs
Normal file
155
NAPS2.Lib/ImportExport/Email/EmailProviderController.cs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
using Eto.Drawing;
|
||||||
|
using NAPS2.EtoForms;
|
||||||
|
using NAPS2.EtoForms.Ui;
|
||||||
|
using NAPS2.ImportExport.Email.Mapi;
|
||||||
|
using NAPS2.ImportExport.Email.Oauth;
|
||||||
|
using NAPS2.Scan;
|
||||||
|
|
||||||
|
namespace NAPS2.ImportExport.Email;
|
||||||
|
|
||||||
|
public class EmailProviderController
|
||||||
|
{
|
||||||
|
private readonly IFormFactory _formFactory;
|
||||||
|
private readonly Naps2Config _config;
|
||||||
|
private readonly SystemEmailClients _systemEmailClients;
|
||||||
|
private readonly GmailOauthProvider _gmailOauthProvider;
|
||||||
|
private readonly OutlookWebOauthProvider _outlookWebOauthProvider;
|
||||||
|
private readonly ThunderbirdEmailProvider _thunderbirdProvider;
|
||||||
|
|
||||||
|
public EmailProviderController(IFormFactory formFactory, Naps2Config config, SystemEmailClients systemEmailClients,
|
||||||
|
GmailOauthProvider gmailOauthProvider, OutlookWebOauthProvider outlookWebOauthProvider,
|
||||||
|
ThunderbirdEmailProvider thunderbirdProvider)
|
||||||
|
{
|
||||||
|
_formFactory = formFactory;
|
||||||
|
_config = config;
|
||||||
|
_systemEmailClients = systemEmailClients;
|
||||||
|
_gmailOauthProvider = gmailOauthProvider;
|
||||||
|
_outlookWebOauthProvider = outlookWebOauthProvider;
|
||||||
|
_thunderbirdProvider = thunderbirdProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmailProviderWidget> GetWidgets()
|
||||||
|
{
|
||||||
|
var providerWidgets = new List<EmailProviderWidget>();
|
||||||
|
var userSetup = _config.Get(c => c.EmailSetup);
|
||||||
|
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
if (OperatingSystem.IsWindowsVersionAtLeast(7))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
var systemClientNames = _systemEmailClients.GetNames();
|
||||||
|
var defaultSystemClientName = _systemEmailClients.GetDefaultName();
|
||||||
|
|
||||||
|
foreach (var clientName in systemClientNames.OrderBy(x =>
|
||||||
|
x == userSetup.SystemProviderName ? 0 : x == defaultSystemClientName ? 1 : 2))
|
||||||
|
{
|
||||||
|
providerWidgets.Add(GetWidget(EmailProviderType.System, clientName));
|
||||||
|
}
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MaybeAddWidget(EmailProviderType type, bool condition)
|
||||||
|
{
|
||||||
|
if (condition)
|
||||||
|
{
|
||||||
|
providerWidgets.Add(GetWidget(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
// For Windows we expect Thunderbird to be used through MAPI. For Linux we need to handle it specially.
|
||||||
|
MaybeAddWidget(EmailProviderType.Thunderbird, !OperatingSystem.IsWindows());
|
||||||
|
#endif
|
||||||
|
MaybeAddWidget(EmailProviderType.Gmail, _gmailOauthProvider.HasClientCreds);
|
||||||
|
MaybeAddWidget(EmailProviderType.OutlookWeb, _outlookWebOauthProvider.HasClientCreds);
|
||||||
|
|
||||||
|
// Sort the currently-selected provider to the top
|
||||||
|
return providerWidgets.OrderBy(widget => widget.ProviderType == userSetup.ProviderType ? 0 : 1).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private EmailProviderWidget GetWidget(EmailProviderType type, string? clientName = null)
|
||||||
|
{
|
||||||
|
return type switch
|
||||||
|
{
|
||||||
|
EmailProviderType.System => new EmailProviderWidget
|
||||||
|
{
|
||||||
|
ProviderType = EmailProviderType.System,
|
||||||
|
ProviderIcon = GetSystemIcon(clientName!) ?? Icons.mail_yellow.ToEtoImage(),
|
||||||
|
ProviderName = clientName!,
|
||||||
|
Choose = () => ChooseSystem(clientName!)
|
||||||
|
},
|
||||||
|
EmailProviderType.Thunderbird => new EmailProviderWidget
|
||||||
|
{
|
||||||
|
ProviderType = EmailProviderType.Thunderbird,
|
||||||
|
ProviderIcon = Icons.thunderbird.ToEtoImage(),
|
||||||
|
ProviderName = EmailProviderType.Thunderbird.Description(),
|
||||||
|
Choose = ChooseThunderbird,
|
||||||
|
// When Thunderbird isn't available, we disable it rather than hide it.
|
||||||
|
// The point is to give a hint to the user that Thunderbird support is present.
|
||||||
|
Enabled = _thunderbirdProvider.IsAvailable
|
||||||
|
},
|
||||||
|
EmailProviderType.Gmail => new EmailProviderWidget
|
||||||
|
{
|
||||||
|
ProviderType = EmailProviderType.Gmail,
|
||||||
|
ProviderIcon = Icons.gmail.ToEtoImage(),
|
||||||
|
ProviderName = EmailProviderType.Gmail.Description(),
|
||||||
|
Choose = () => ChooseOauth(_gmailOauthProvider)
|
||||||
|
},
|
||||||
|
EmailProviderType.OutlookWeb => new EmailProviderWidget
|
||||||
|
{
|
||||||
|
ProviderType = EmailProviderType.OutlookWeb,
|
||||||
|
ProviderIcon = Icons.outlookweb.ToEtoImage(),
|
||||||
|
ProviderName = EmailProviderType.OutlookWeb.Description(),
|
||||||
|
Choose = () => ChooseOauth(_outlookWebOauthProvider)
|
||||||
|
},
|
||||||
|
// EmailProviderType.CustomSmtp => new EmailProviderWidget
|
||||||
|
// {
|
||||||
|
// ProviderType = EmailProviderType.CustomSmtp,
|
||||||
|
// ProviderIcon = Icons.email_setting.ToEtoImage(),
|
||||||
|
// ProviderName = EmailProviderType.CustomSmtp.Description(),
|
||||||
|
// Choose = ChooseCustomSmtp
|
||||||
|
// },
|
||||||
|
_ => throw new ArgumentException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap? GetSystemIcon(string clientName)
|
||||||
|
{
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
if (!OperatingSystem.IsWindowsVersionAtLeast(7))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
var exePath = _systemEmailClients.GetExePath(clientName);
|
||||||
|
return exePath == null ? null : EtoPlatform.Current.ExtractAssociatedIcon(exePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ChooseSystem(string clientName)
|
||||||
|
{
|
||||||
|
var transact = _config.User.BeginTransaction();
|
||||||
|
transact.Remove(c => c.EmailSetup);
|
||||||
|
transact.Set(c => c.EmailSetup.SystemProviderName, clientName);
|
||||||
|
transact.Set(c => c.EmailSetup.ProviderType, EmailProviderType.System);
|
||||||
|
transact.Commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ChooseThunderbird()
|
||||||
|
{
|
||||||
|
var transact = _config.User.BeginTransaction();
|
||||||
|
transact.Remove(c => c.EmailSetup);
|
||||||
|
transact.Set(c => c.EmailSetup.ProviderType, EmailProviderType.Thunderbird);
|
||||||
|
transact.Commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ChooseOauth(OauthProvider provider)
|
||||||
|
{
|
||||||
|
var authForm = _formFactory.Create<AuthorizeForm>();
|
||||||
|
authForm.OauthProvider = provider;
|
||||||
|
authForm.ShowModal();
|
||||||
|
return authForm.Result;
|
||||||
|
}
|
||||||
|
}
|
12
NAPS2.Lib/ImportExport/Email/EmailProviderWidget.cs
Normal file
12
NAPS2.Lib/ImportExport/Email/EmailProviderWidget.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using Eto.Drawing;
|
||||||
|
|
||||||
|
namespace NAPS2.ImportExport.Email;
|
||||||
|
|
||||||
|
public class EmailProviderWidget
|
||||||
|
{
|
||||||
|
public required EmailProviderType ProviderType { get; init; }
|
||||||
|
public required Bitmap ProviderIcon { get; init; }
|
||||||
|
public required string ProviderName { get; init; }
|
||||||
|
public required Func<bool> Choose { get; init; }
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user