Form thread safety
This commit is contained in:
parent
7848366818
commit
1fdcea929f
@ -1,5 +1,6 @@
|
||||
using AudibleApi;
|
||||
using AudibleUtilities;
|
||||
using Avalonia.Threading;
|
||||
using LibationUiBase.Forms;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -17,42 +18,46 @@ namespace LibationAvalonia.Dialogs.Login
|
||||
}
|
||||
|
||||
public async Task<string> Get2faCodeAsync(string prompt)
|
||||
=> await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
var dialog = new _2faCodeDialog(prompt);
|
||||
if (await dialog.ShowDialogAsync() is DialogResult.OK)
|
||||
return dialog.Code;
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
public async Task<(string password, string guess)> GetCaptchaAnswerAsync(string password, byte[] captchaImage)
|
||||
=> await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
var dialog = new CaptchaDialog(password, captchaImage);
|
||||
if (await dialog.ShowDialogAsync() is DialogResult.OK)
|
||||
return (dialog.Password, dialog.Answer);
|
||||
return (null, null);
|
||||
}
|
||||
});
|
||||
|
||||
public async Task<(string name, string value)> GetMfaChoiceAsync(MfaConfig mfaConfig)
|
||||
=> await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
var dialog = new MfaDialog(mfaConfig);
|
||||
if (await dialog.ShowDialogAsync() is DialogResult.OK)
|
||||
return (dialog.SelectedName, dialog.SelectedValue);
|
||||
return (null, null);
|
||||
}
|
||||
});
|
||||
|
||||
public async Task<(string email, string password)> GetLoginAsync()
|
||||
=> await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
var dialog = new LoginCallbackDialog(_account);
|
||||
if (await dialog.ShowDialogAsync() is DialogResult.OK)
|
||||
return (_account.AccountId, dialog.Password);
|
||||
return (null, null);
|
||||
}
|
||||
});
|
||||
|
||||
public async Task ShowApprovalNeededAsync()
|
||||
=> await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
var dialog = new ApprovalNeededDialog();
|
||||
await dialog.ShowDialogAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using AudibleApi;
|
||||
using AudibleUtilities;
|
||||
using Avalonia.Threading;
|
||||
using LibationFileManager;
|
||||
using LibationUiBase.Forms;
|
||||
using System;
|
||||
@ -21,6 +22,9 @@ namespace LibationAvalonia.Dialogs.Login
|
||||
}
|
||||
|
||||
public async Task<ChoiceOut?> StartAsync(ChoiceIn choiceIn)
|
||||
=> await Dispatcher.UIThread.InvokeAsync(() => StartAsyncInternal(choiceIn));
|
||||
|
||||
private async Task<ChoiceOut?> StartAsyncInternal(ChoiceIn choiceIn)
|
||||
{
|
||||
if (Configuration.IsWindows && Environment.OSVersion.Version.Major >= 10)
|
||||
{
|
||||
|
||||
@ -22,7 +22,7 @@ namespace LibationAvalonia.Views
|
||||
public MainWindow()
|
||||
{
|
||||
DataContext = new MainVM(this);
|
||||
ApiExtended.LoginChoiceFactory = account => new Dialogs.Login.AvaloniaLoginChoiceEager(account);
|
||||
ApiExtended.LoginChoiceFactory = account => Dispatcher.UIThread.Invoke(() => new Dialogs.Login.AvaloniaLoginChoiceEager(account));
|
||||
|
||||
AudibleApiStorage.LoadError += AudibleApiStorage_LoadError;
|
||||
InitializeComponent();
|
||||
|
||||
@ -5,18 +5,19 @@ namespace LibationWinForms.Dialogs.Login
|
||||
{
|
||||
public abstract class WinformLoginBase
|
||||
{
|
||||
private readonly IWin32Window _owner;
|
||||
protected WinformLoginBase(IWin32Window owner)
|
||||
protected Control Owner { get; }
|
||||
protected WinformLoginBase(Control owner)
|
||||
{
|
||||
_owner = owner;
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
/// <returns>True if ShowDialog's DialogResult == OK</returns>
|
||||
protected bool ShowDialog(Form dialog)
|
||||
=> Owner.Invoke(() =>
|
||||
{
|
||||
var result = dialog.ShowDialog(_owner);
|
||||
var result = dialog.ShowDialog(Owner);
|
||||
Serilog.Log.Logger.Debug("{@DebugInfo}", new { DialogResult = result });
|
||||
return result == DialogResult.OK;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,48 +13,53 @@ namespace LibationWinForms.Login
|
||||
|
||||
public string DeviceName { get; } = "Libation";
|
||||
|
||||
public WinformLoginCallback(Account account, IWin32Window owner) : base(owner)
|
||||
public WinformLoginCallback(Account account, Control owner) : base(owner)
|
||||
{
|
||||
_account = Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account));
|
||||
}
|
||||
|
||||
public Task<string> Get2faCodeAsync(string prompt)
|
||||
=> Owner.Invoke(() =>
|
||||
{
|
||||
using var dialog = new _2faCodeDialog(prompt);
|
||||
if (ShowDialog(dialog))
|
||||
return Task.FromResult(dialog.Code);
|
||||
return Task.FromResult<string>(null);
|
||||
}
|
||||
});
|
||||
|
||||
public Task<(string password, string guess)> GetCaptchaAnswerAsync(string password, byte[] captchaImage)
|
||||
=> Owner.Invoke(() =>
|
||||
{
|
||||
using var dialog = new CaptchaDialog(password, captchaImage);
|
||||
if (ShowDialog(dialog))
|
||||
return Task.FromResult((dialog.Password, dialog.Answer));
|
||||
return Task.FromResult<(string, string)>((null,null));
|
||||
}
|
||||
return Task.FromResult<(string, string)>((null, null));
|
||||
});
|
||||
|
||||
public Task<(string name, string value)> GetMfaChoiceAsync(MfaConfig mfaConfig)
|
||||
=> Owner.Invoke(() =>
|
||||
{
|
||||
using var dialog = new MfaDialog(mfaConfig);
|
||||
if (ShowDialog(dialog))
|
||||
return Task.FromResult((dialog.SelectedName, dialog.SelectedValue));
|
||||
return Task.FromResult<(string, string)>((null, null));
|
||||
}
|
||||
});
|
||||
|
||||
public Task<(string email, string password)> GetLoginAsync()
|
||||
=> Owner.Invoke(() =>
|
||||
{
|
||||
using var dialog = new LoginCallbackDialog(_account);
|
||||
if (ShowDialog(dialog))
|
||||
return Task.FromResult((dialog.Email, dialog.Password));
|
||||
return Task.FromResult<(string, string)>((null, null));
|
||||
}
|
||||
});
|
||||
|
||||
public Task ShowApprovalNeededAsync()
|
||||
=> Owner.Invoke(() =>
|
||||
{
|
||||
using var dialog = new ApprovalNeededDialog();
|
||||
ShowDialog(dialog);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -13,13 +13,16 @@ namespace LibationWinForms.Login
|
||||
|
||||
private Account _account { get; }
|
||||
|
||||
public WinformLoginChoiceEager(Account account, IWin32Window owner) : base(owner)
|
||||
public WinformLoginChoiceEager(Account account, Control owner) : base(owner)
|
||||
{
|
||||
_account = Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account));
|
||||
LoginCallback = new WinformLoginCallback(_account, owner);
|
||||
}
|
||||
|
||||
public Task<ChoiceOut> StartAsync(ChoiceIn choiceIn)
|
||||
=> Owner.Invoke(() => StartAsyncInternal(choiceIn));
|
||||
|
||||
private Task<ChoiceOut> StartAsyncInternal(ChoiceIn choiceIn)
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 10)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user