mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-13 06:07:30 -04:00
The blank grid said nothing, and the only pointer anywhere was the status bar's
'No books. Begin by importing your library' - which is the wrong advice for
someone who has not added an account yet, since Import has nothing to scan.
An empty library has two causes with different next steps, and AccountsCount
already knows which one applies, so say the one that fits and offer the action
that goes with it:
no accounts Libation is empty.
Add your Audible account, then scan your library ...
[Add Account] [Take a Guided Tour]
no books No books in your library yet.
Scan your Audible account to bring your books in.
[Scan Library] [Take a Guided Tour]
The buttons run the same commands the menu items do, so the two cannot drift.
The tour is there because it is offered once on first launch and never again
once declined; Settings > Take a Guided Tour is not somewhere a new user looks.
Held back until LibraryStats has been counted at least once, which is what keeps
'Add your Audible account' off the screen in the moment between the window
appearing and a full library loading, and held back mid-scan. An empty library
takes precedence over an empty filter result, since 'no books match' is true but
useless when there are no books at all.
Both grid empty states now share one set of strings in GridEmptyStateUi rather
than the no-matches pair living in TrashBinUi, which was already the wrong home
for them and would only get worse with a third.
Co-authored-by: rmcrackan <rmcrackan@gmail.com>
135 lines
4.4 KiB
C#
135 lines
4.4 KiB
C#
using ApplicationServices;
|
|
using AudibleUtilities;
|
|
using LibationFileManager;
|
|
using LibationUiBase;
|
|
using LibationWinForms.Dialogs;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace LibationWinForms;
|
|
|
|
// this is for manual scan/import. Unrelated to auto-scan
|
|
public partial class Form1
|
|
{
|
|
private void Configure_ScanManual()
|
|
{
|
|
this.Load += refreshImportMenu;
|
|
AccountsSettingsPersister.Saved += (_, _) => Invoke(refreshImportMenu, null, null);
|
|
locateAudiobooksToolStripMenuItem.ToolTipText = Configuration.GetHelpText("LocateAudiobooks");
|
|
}
|
|
|
|
private void refreshImportMenu(object? _, EventArgs? __)
|
|
{
|
|
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
|
|
var count = persister.AccountsSettings.Accounts.Count;
|
|
|
|
autoScanLibraryToolStripMenuItem.Visible = count > 0;
|
|
|
|
noAccountsYetAddAccountToolStripMenuItem.Visible = count == 0;
|
|
scanLibraryToolStripMenuItem.Visible = count == 1;
|
|
scanLibraryOfAllAccountsToolStripMenuItem.Visible = count > 1;
|
|
scanLibraryOfSomeAccountsToolStripMenuItem.Visible = count > 1;
|
|
|
|
setAnyAccounts(count > 0);
|
|
|
|
removeLibraryBooksToolStripMenuItem.Visible = count > 0;
|
|
removeSomeAccountsToolStripMenuItem.Visible = count > 1;
|
|
removeAllAccountsToolStripMenuItem.Visible = count > 1;
|
|
}
|
|
|
|
private void noAccountsYetAddAccountToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show("To load your Audible library, come back here to the Import menu after adding your account");
|
|
new AccountsDialog().ShowDialog();
|
|
}
|
|
|
|
private async void scanLibraryToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
|
|
if (persister.AccountsSettings.GetAll().FirstOrDefault() is { } firstAccount)
|
|
await scanLibrariesAsync(firstAccount);
|
|
}
|
|
|
|
private async void scanLibraryOfAllAccountsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
|
|
var allAccounts = persister.AccountsSettings.GetAll();
|
|
await scanLibrariesAsync(allAccounts);
|
|
}
|
|
|
|
private async void scanLibraryOfSomeAccountsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
using var scanAccountsDialog = new ScanAccountsDialog();
|
|
|
|
if (scanAccountsDialog.ShowDialog() != DialogResult.OK)
|
|
return;
|
|
|
|
if (!scanAccountsDialog.CheckedAccounts.Any())
|
|
return;
|
|
|
|
await scanLibrariesAsync(scanAccountsDialog.CheckedAccounts);
|
|
}
|
|
|
|
private async Task scanLibrariesAsync(IEnumerable<Account> accounts) => await scanLibrariesAsync(accounts.ToArray());
|
|
private async Task scanLibrariesAsync(params Account[] accounts)
|
|
{
|
|
try
|
|
{
|
|
var (totalProcessed, newAdded) = await Task.Run(() => LibraryCommands.ImportAccountAsync(accounts));
|
|
autoScanRunner?.OnManualScanSucceeded();
|
|
|
|
// this is here instead of ScanEnd so that the following is only possible when it's user-initiated, not automatic loop
|
|
if (Configuration.Instance.ShowImportedStats && newAdded > 0)
|
|
MessageBox.Show($"Total processed: {totalProcessed}\r\nNew: {newAdded}");
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
Serilog.Log.Information("Audible login attempt cancelled by user");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (WebView2LoginErrorMessage.TryFindInTree(ex, out var webViewEx) && webViewEx is not null)
|
|
{
|
|
MessageBoxLib.ShowAdminAlert(
|
|
this,
|
|
WebView2LoginErrorMessage.ExplainerBody,
|
|
WebView2LoginErrorMessage.Caption,
|
|
webViewEx);
|
|
}
|
|
else if (NonJsonResponseExceptionExtensions.TryFindInTree(ex, out var htmlEx) && htmlEx is not null)
|
|
{
|
|
MessageBoxLib.ShowAdminAlert(
|
|
this,
|
|
htmlEx.GetExplainerBody(),
|
|
NonJsonResponseExceptionExtensions.LibraryScanFailedCaption,
|
|
htmlEx);
|
|
}
|
|
else
|
|
{
|
|
MessageBoxLib.ShowAdminAlert(
|
|
this,
|
|
"Error importing library. Please try again. If this still happens after 2 or 3 tries, stop and contact administrator",
|
|
"Error importing library",
|
|
ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void locateAudiobooksToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var result = MessageBox.Show(
|
|
this,
|
|
Configuration.GetHelpText(nameof(LocateAudiobooksDialog)),
|
|
"Locate Previously-Liberated Audiobook Files",
|
|
MessageBoxButtons.OKCancel,
|
|
MessageBoxIcon.Information,
|
|
MessageBoxDefaultButton.Button1);
|
|
|
|
if (result is DialogResult.OK)
|
|
new LocateAudiobooksDialog().ShowDialog();
|
|
}
|
|
}
|