Libation Runs on MacOS
This commit is contained in:
parent
8020ded642
commit
0bfa609058
30 changed files with 147 additions and 171 deletions
|
|
@ -136,7 +136,7 @@ namespace LibationAvalonia.Dialogs
|
|||
|
||||
if (persister.AccountsSettings.Accounts.Any(a => a.AccountId == account.AccountId && a.IdentityTokens.Locale.Name == account.Locale.Name))
|
||||
{
|
||||
MessageBox.Show(this, $"An account with that account id and country already exists.\r\n\r\nAccount ID: {account.AccountId}\r\nCountry: {account.Locale.Name}", "Cannot Add Duplicate Account");
|
||||
await MessageBox.Show(this, $"An account with that account id and country already exists.\r\n\r\nAccount ID: {account.AccountId}\r\nCountry: {account.Locale.Name}", "Cannot Add Duplicate Account");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ namespace LibationAvalonia.Dialogs
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.ShowAdminAlert(
|
||||
await MessageBox.ShowAdminAlert(
|
||||
this,
|
||||
$"An error occurred while importing an account from:\r\n{filePath[0]}\r\n\r\nIs the file encrypted?",
|
||||
"Error Importing Account",
|
||||
|
|
@ -160,11 +160,11 @@ namespace LibationAvalonia.Dialogs
|
|||
Export(acc);
|
||||
}
|
||||
|
||||
protected override void SaveAndClose()
|
||||
protected override async Task SaveAndCloseAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!inputIsValid())
|
||||
if (!await inputIsValid())
|
||||
return;
|
||||
|
||||
// without transaction, accounts persister will write ANY EDIT immediately to file
|
||||
|
|
@ -178,7 +178,7 @@ namespace LibationAvalonia.Dialogs
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.ShowAdminAlert(this, "Error attempting to save accounts", "Error saving accounts", ex);
|
||||
await MessageBox.ShowAdminAlert(this, "Error attempting to save accounts", "Error saving accounts", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ namespace LibationAvalonia.Dialogs
|
|||
: dto.AccountName.Trim();
|
||||
}
|
||||
}
|
||||
private bool inputIsValid()
|
||||
private async Task<bool> inputIsValid()
|
||||
{
|
||||
foreach (var dto in Accounts.ToList())
|
||||
{
|
||||
|
|
@ -233,13 +233,13 @@ namespace LibationAvalonia.Dialogs
|
|||
|
||||
if (string.IsNullOrWhiteSpace(dto.AccountId))
|
||||
{
|
||||
MessageBox.Show(this, "Account id cannot be blank. Please enter an account id for all accounts.", "Blank account", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show(this, "Account id cannot be blank. Please enter an account id for all accounts.", "Blank account", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(dto.SelectedLocale?.Name))
|
||||
{
|
||||
MessageBox.Show(this, "Please select a locale (i.e.: country or region) for all accounts.", "Blank region", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show(this, "Please select a locale (i.e.: country or region) for all accounts.", "Blank region", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ namespace LibationAvalonia.Dialogs
|
|||
|
||||
if (account.IdentityTokens?.IsValid != true)
|
||||
{
|
||||
MessageBox.Show(this, "This account hasn't been authenticated yet. First scan your library to log into your account, then try exporting again.", "Account Not Authenticated");
|
||||
await MessageBox.Show(this, "This account hasn't been authenticated yet. First scan your library to log into your account, then try exporting again.", "Account Not Authenticated");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -282,11 +282,11 @@ namespace LibationAvalonia.Dialogs
|
|||
|
||||
File.WriteAllText(fileName, jsonText);
|
||||
|
||||
MessageBox.Show(this, $"Successfully exported {account.AccountName} to\r\n\r\n{fileName}", "Success!");
|
||||
await MessageBox.Show(this, $"Successfully exported {account.AccountName} to\r\n\r\n{fileName}", "Success!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.ShowAdminAlert(
|
||||
await MessageBox.ShowAdminAlert(
|
||||
this,
|
||||
$"An error occurred while exporting account:\r\n{account.AccountName}",
|
||||
"Error Exporting Account",
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ namespace LibationAvalonia.Dialogs
|
|||
}
|
||||
protected override async Task SaveAndCloseAsync()
|
||||
{
|
||||
if (!_viewModel.Validate())
|
||||
if (!await _viewModel.Validate())
|
||||
return;
|
||||
|
||||
TemplateText = _viewModel.workingTemplateText;
|
||||
|
|
@ -115,7 +115,7 @@ namespace LibationAvalonia.Dialogs
|
|||
|
||||
public void resetTextBox(string value) => workingTemplateText = value;
|
||||
|
||||
public bool Validate()
|
||||
public async Task<bool> Validate()
|
||||
{
|
||||
if (template.IsValid(workingTemplateText))
|
||||
return true;
|
||||
|
|
@ -123,7 +123,7 @@ namespace LibationAvalonia.Dialogs
|
|||
.GetErrors(workingTemplateText)
|
||||
.Select(err => $"- {err}")
|
||||
.Aggregate((a, b) => $"{a}\r\n{b}");
|
||||
MessageBox.Show($"This template text is not valid. Errors:\r\n{errors}", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show($"This template text is not valid. Errors:\r\n{errors}", "Invalid", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace LibationAvalonia.Dialogs
|
|||
catch (Exception ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, $"Failed to save picture to {fileName}");
|
||||
MessageBox.Show(this, $"An error was encountered while trying to save the picture\r\n\r\n{ex.Message}", "Failed to save picture", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
|
||||
await MessageBox.Show(this, $"An error was encountered while trying to save the picture\r\n\r\n{ex.Message}", "Failed to save picture", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ namespace LibationAvalonia.Dialogs
|
|||
DataContext = dirSelectOptions = new();
|
||||
}
|
||||
|
||||
public void SaveButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
public async void SaveButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
|
||||
var libationDir = dirSelectOptions.Directory;
|
||||
|
||||
if (!System.IO.Directory.Exists(libationDir))
|
||||
{
|
||||
MessageBox.Show("Not saving change to Libation Files location. This folder does not exist:\r\n" + libationDir, "Folder does not exist", MessageBoxButtons.OK, MessageBoxIcon.Error, saveAndRestorePosition: false);
|
||||
await MessageBox.Show("Not saving change to Libation Files location. This folder does not exist:\r\n" + libationDir, "Folder does not exist", MessageBoxButtons.OK, MessageBoxIcon.Error, saveAndRestorePosition: false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ namespace LibationAvalonia.Dialogs.Login
|
|||
{
|
||||
|
||||
/// <returns>True if ShowDialog's DialogResult == OK</returns>
|
||||
protected static bool ShowDialog(DialogWindow dialog)
|
||||
protected static async Task<bool> ShowDialog(DialogWindow dialog)
|
||||
{
|
||||
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
|
||||
return false;
|
||||
|
||||
var result = dialog.ShowDialogSynchronously<DialogResult>(desktop.MainWindow);
|
||||
var result = await dialog.ShowDialog<DialogResult>(desktop.MainWindow);
|
||||
Serilog.Log.Logger.Debug("{@DebugInfo}", new { DialogResult = result });
|
||||
return result == DialogResult.OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using AudibleApi;
|
||||
using AudibleUtilities;
|
||||
|
||||
|
|
@ -13,43 +14,43 @@ namespace LibationAvalonia.Dialogs.Login
|
|||
_account = Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account));
|
||||
}
|
||||
|
||||
public string Get2faCode()
|
||||
public async Task<string> Get2faCodeAsync()
|
||||
{
|
||||
var dialog = new _2faCodeDialog();
|
||||
if (ShowDialog(dialog))
|
||||
if (await ShowDialog(dialog))
|
||||
return dialog.Code;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetCaptchaAnswer(byte[] captchaImage)
|
||||
public async Task<string> GetCaptchaAnswerAsync(byte[] captchaImage)
|
||||
{
|
||||
var dialog = new CaptchaDialog(captchaImage);
|
||||
if (ShowDialog(dialog))
|
||||
if (await ShowDialog(dialog))
|
||||
return dialog.Answer;
|
||||
return null;
|
||||
}
|
||||
|
||||
public (string name, string value) GetMfaChoice(MfaConfig mfaConfig)
|
||||
public async Task<(string name, string value)> GetMfaChoiceAsync(MfaConfig mfaConfig)
|
||||
{
|
||||
var dialog = new MfaDialog(mfaConfig);
|
||||
if (ShowDialog(dialog))
|
||||
if (await ShowDialog(dialog))
|
||||
return (dialog.SelectedName, dialog.SelectedValue);
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
public (string email, string password) GetLogin()
|
||||
public async Task<(string email, string password)> GetLoginAsync()
|
||||
{
|
||||
var dialog = new LoginCallbackDialog(_account);
|
||||
if (ShowDialog(dialog))
|
||||
if (await ShowDialog(dialog))
|
||||
return (_account.AccountId, dialog.Password);
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
public void ShowApprovalNeeded()
|
||||
public async Task ShowApprovalNeededAsync()
|
||||
{
|
||||
var dialog = new ApprovalNeededDialog();
|
||||
ShowDialog(dialog);
|
||||
await ShowDialog(dialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,11 +20,11 @@ namespace LibationAvalonia.Dialogs.Login
|
|||
LoginCallback = new AvaloniaLoginCallback(_account);
|
||||
}
|
||||
|
||||
public ChoiceOut Start(ChoiceIn choiceIn)
|
||||
public async Task<ChoiceOut> StartAsync(ChoiceIn choiceIn)
|
||||
{
|
||||
var dialog = new LoginChoiceEagerDialog(_account);
|
||||
|
||||
if (!ShowDialog(dialog))
|
||||
if (!await ShowDialog(dialog))
|
||||
return null;
|
||||
|
||||
|
||||
|
|
@ -33,15 +33,16 @@ namespace LibationAvalonia.Dialogs.Login
|
|||
case LoginMethod.Api:
|
||||
return ChoiceOut.WithApi(dialog.Account.AccountId, dialog.Password);
|
||||
case LoginMethod.External:
|
||||
{
|
||||
var externalDialog = new LoginExternalDialog(_account, choiceIn.LoginUrl);
|
||||
return ShowDialog(externalDialog)
|
||||
? ChoiceOut.External(externalDialog.ResponseUrl)
|
||||
: null;
|
||||
}
|
||||
{
|
||||
var externalDialog = new LoginExternalDialog(_account, choiceIn.LoginUrl);
|
||||
return await ShowDialog(externalDialog)
|
||||
? ChoiceOut.External(externalDialog.ResponseUrl)
|
||||
: null;
|
||||
}
|
||||
default:
|
||||
throw new Exception($"Unknown {nameof(LoginMethod)} value");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace LibationAvalonia.Dialogs.Login
|
|||
Serilog.Log.Logger.Information("Submit button clicked: {@DebugInfo}", new { ResponseUrl });
|
||||
if (!Uri.TryCreate(ResponseUrl, UriKind.Absolute, out var result))
|
||||
{
|
||||
MessageBox.Show("Invalid response URL");
|
||||
await MessageBox.Show("Invalid response URL");
|
||||
return;
|
||||
}
|
||||
await base.SaveAndCloseAsync();
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace LibationAvalonia.Dialogs.Login
|
|||
});
|
||||
if (selected is null)
|
||||
{
|
||||
MessageBox.Show("No MFA option selected", "None selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show("No MFA option selected", "None selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace LibationAvalonia.Dialogs
|
|||
DataContext = this;
|
||||
}
|
||||
|
||||
private void GoToGithub_Tapped(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
private async void GoToGithub_Tapped(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
var url = "https://github.com/rmcrackan/Libation/issues";
|
||||
try
|
||||
|
|
@ -37,11 +37,11 @@ namespace LibationAvalonia.Dialogs
|
|||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show($"Error opening url\r\n{url}", "Error opening url", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show($"Error opening url\r\n{url}", "Error opening url", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void GoToLogs_Tapped(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
private async void GoToLogs_Tapped(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
LongPath dir = "";
|
||||
try
|
||||
|
|
@ -56,7 +56,7 @@ namespace LibationAvalonia.Dialogs
|
|||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show($"Error opening folder\r\n{dir}", "Error opening folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show($"Error opening folder\r\n{dir}", "Error opening folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ namespace LibationAvalonia.Dialogs
|
|||
|
||||
protected override async Task SaveAndCloseAsync()
|
||||
{
|
||||
if (!settingsDisp.SaveSettings(config))
|
||||
if (!await settingsDisp.SaveSettingsAsync(config))
|
||||
return;
|
||||
|
||||
MessageBox.VerboseLoggingWarning_ShowIfTrue();
|
||||
await MessageBox.VerboseLoggingWarning_ShowIfTrue();
|
||||
await base.SaveAndCloseAsync();
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ namespace LibationAvalonia.Dialogs
|
|||
internal interface ISettingsDisplay
|
||||
{
|
||||
void LoadSettings(Configuration config);
|
||||
bool SaveSettings(Configuration config);
|
||||
Task<bool> SaveSettingsAsync(Configuration config);
|
||||
}
|
||||
|
||||
public class SettingsPages : ISettingsDisplay
|
||||
|
|
@ -120,12 +120,12 @@ namespace LibationAvalonia.Dialogs
|
|||
AudioSettings = new(config);
|
||||
}
|
||||
|
||||
public bool SaveSettings(Configuration config)
|
||||
public async Task<bool> SaveSettingsAsync(Configuration config)
|
||||
{
|
||||
var result = ImportantSettings.SaveSettings(config);
|
||||
result &= ImportSettings.SaveSettings(config);
|
||||
result &= DownloadDecryptSettings.SaveSettings(config);
|
||||
result &= AudioSettings.SaveSettings(config);
|
||||
var result = await ImportantSettings.SaveSettingsAsync(config);
|
||||
result &= await ImportSettings.SaveSettingsAsync(config);
|
||||
result &= await DownloadDecryptSettings.SaveSettingsAsync(config);
|
||||
result &= await AudioSettings.SaveSettingsAsync(config);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -146,13 +146,13 @@ namespace LibationAvalonia.Dialogs
|
|||
BetaOptIn = config.BetaOptIn;
|
||||
}
|
||||
|
||||
public bool SaveSettings(Configuration config)
|
||||
public async Task<bool> SaveSettingsAsync(Configuration config)
|
||||
{
|
||||
#region validation
|
||||
|
||||
if (string.IsNullOrWhiteSpace(BooksDirectory))
|
||||
{
|
||||
MessageBox.Show("Cannot set Books Location to blank", "Location is blank", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
await MessageBox.Show("Cannot set Books Location to blank", "Location is blank", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -204,14 +204,14 @@ namespace LibationAvalonia.Dialogs
|
|||
AutoDownloadEpisodes = config.AutoDownloadEpisodes;
|
||||
}
|
||||
|
||||
public bool SaveSettings(Configuration config)
|
||||
public Task<bool> SaveSettingsAsync(Configuration config)
|
||||
{
|
||||
config.AutoScan = AutoScan;
|
||||
config.ShowImportedStats = ShowImportedStats;
|
||||
config.ImportEpisodes = ImportEpisodes;
|
||||
config.DownloadEpisodes = DownloadEpisodes;
|
||||
config.AutoDownloadEpisodes = AutoDownloadEpisodes;
|
||||
return true;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public string AutoScanText { get; } = Configuration.GetDescription(nameof(Configuration.AutoScan));
|
||||
|
|
@ -259,25 +259,25 @@ namespace LibationAvalonia.Dialogs
|
|||
: Configuration.GetKnownDirectory(config.InProgress);
|
||||
}
|
||||
|
||||
public bool SaveSettings(Configuration config)
|
||||
public async Task<bool> SaveSettingsAsync(Configuration config)
|
||||
{
|
||||
static void validationError(string text, string caption)
|
||||
static Task validationError(string text, string caption)
|
||||
=> MessageBox.Show(text, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
// these 3 should do nothing. Configuration will only init these with a valid value. EditTemplateDialog ensures valid before returning
|
||||
if (!Templates.Folder.IsValid(FolderTemplate))
|
||||
{
|
||||
validationError($"Not saving change to folder naming template. Invalid format.", "Invalid folder template");
|
||||
await validationError($"Not saving change to folder naming template. Invalid format.", "Invalid folder template");
|
||||
return false;
|
||||
}
|
||||
if (!Templates.File.IsValid(FileTemplate))
|
||||
{
|
||||
validationError($"Not saving change to file naming template. Invalid format.", "Invalid file template");
|
||||
await validationError($"Not saving change to file naming template. Invalid format.", "Invalid file template");
|
||||
return false;
|
||||
}
|
||||
if (!Templates.ChapterFile.IsValid(ChapterFileTemplate))
|
||||
{
|
||||
validationError($"Not saving change to chapter file naming template. Invalid format.", "Invalid chapter file template");
|
||||
await validationError($"Not saving change to chapter file naming template. Invalid format.", "Invalid chapter file template");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +405,7 @@ namespace LibationAvalonia.Dialogs
|
|||
LameVBRQuality = config.LameVBRQuality;
|
||||
}
|
||||
|
||||
public bool SaveSettings(Configuration config)
|
||||
public Task<bool> SaveSettingsAsync(Configuration config)
|
||||
{
|
||||
config.CreateCueSheet = CreateCueSheet;
|
||||
config.AllowLibationFixup = AllowLibationFixup;
|
||||
|
|
@ -424,7 +424,7 @@ namespace LibationAvalonia.Dialogs
|
|||
config.LameBitrate = LameBitrate;
|
||||
config.LameVBRQuality = LameVBRQuality;
|
||||
|
||||
return true;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public string CreateCueSheetText { get; } = Configuration.GetDescription(nameof(Configuration.CreateCueSheet));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue