mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-12 21:57:19 -04:00
Libation asked GitHub for a newer release every time it started, with no way to stop it. That is noise for anyone whose install is updated by something else - a package manager, or an AppImage updater - because the prompt it raises is one they can do nothing useful with. Add CheckForUpgradesAtStartup, on by default so nothing changes for people who rely on the prompt. Only the automatic check is optional: the About window's "Check for Upgrade" button and the CLI's `version --check` ask for a check outright, so they run either way. That is why the setting is read in a new CheckForUpgradeAtStartupAsync rather than inside CheckForUpgradeAsync, which the startup path and the About button share. The new setting takes the slot of BetaOptIn, which is deleted here. It was declared, described and logged, but no axaml or designer ever bound it and nothing read the value: GetLatestRelease only ever asks for the stable release, so there was no beta channel for it to select. A stale BetaOptIn key in an existing Settings.json needs no migration, since PersistentDictionary ignores keys with no matching property. Closes #1999 Co-authored-by: rmcrackan <rmcrackan@gmail.com>
241 lines
9.0 KiB
C#
241 lines
9.0 KiB
C#
using AudibleApi.Authorization;
|
|
using AudibleUtilities;
|
|
using Dinah.Core;
|
|
using FileManager;
|
|
using LibationFileManager;
|
|
using LibationUiBase;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace LibationWinForms.Dialogs;
|
|
|
|
public partial class SettingsDialog
|
|
{
|
|
private void logsBtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (File.Exists(LogFileFilter.LogFilePath))
|
|
Go.To.File(LogFileFilter.LogFilePath);
|
|
else
|
|
Go.To.Folder(Configuration.Instance.LibationFiles.Location.ShortPathName);
|
|
}
|
|
private Configuration.Theme themeVariant;
|
|
private Configuration.Theme initialThemeVariant;
|
|
private TokenStorageMethod initialTokenStorageMethod;
|
|
private bool osSecretStoreAvailable;
|
|
|
|
private void Load_Important(Configuration config)
|
|
{
|
|
{
|
|
loggingLevelCb.Items.Clear();
|
|
foreach (var level in Enum<Serilog.Events.LogEventLevel>.GetValues())
|
|
loggingLevelCb.Items.Add(level);
|
|
loggingLevelCb.SelectedItem = config.LogLevel;
|
|
}
|
|
|
|
booksLocationDescLbl.Text = desc(nameof(config.Books));
|
|
saveEpisodesToSeriesFolderCbox.Text = desc(nameof(config.SavePodcastsToParentFolder));
|
|
overwriteExistingCbox.Text = desc(nameof(config.OverwriteExisting));
|
|
creationTimeLbl.Text = desc(nameof(config.CreationTime));
|
|
lastWriteTimeLbl.Text = desc(nameof(config.LastWriteTime));
|
|
gridScaleFactorLbl.Text = desc(nameof(config.GridScaleFactor));
|
|
gridFontScaleFactorLbl.Text = desc(nameof(config.GridFontScaleFactor));
|
|
checkForUpgradesCbox.Text = desc(nameof(config.CheckForUpgradesAtStartup));
|
|
toolTip.SetToolTip(checkForUpgradesCbox, Configuration.GetHelpText(nameof(config.CheckForUpgradesAtStartup)));
|
|
|
|
var dateTimeSources = Enum.GetValues<Configuration.DateTimeSource>().Select(v => new EnumDisplay<Configuration.DateTimeSource>(v)).ToArray();
|
|
creationTimeCb.Items.AddRange(dateTimeSources);
|
|
lastWriteTimeCb.Items.AddRange(dateTimeSources);
|
|
|
|
creationTimeCb.SelectedItem = dateTimeSources.SingleOrDefault(v => v.Value == config.CreationTime) ?? dateTimeSources[0];
|
|
lastWriteTimeCb.SelectedItem = dateTimeSources.SingleOrDefault(v => v.Value == config.LastWriteTime) ?? dateTimeSources[0];
|
|
|
|
themeVariant = initialThemeVariant = config.ThemeVariant;
|
|
var themes = Enum.GetValues<Configuration.Theme>().Select(v => new EnumDisplay<Configuration.Theme>(v)).ToArray();
|
|
themeCb.Items.AddRange(themes);
|
|
themeCb.SelectedItem = themes.SingleOrDefault(v => v.Value == themeVariant) ?? themes[0];
|
|
|
|
booksSelectControl.SetSearchTitle("books location");
|
|
booksSelectControl.SetDirectoryItems(
|
|
new()
|
|
{
|
|
Configuration.KnownDirectories.UserProfile,
|
|
Configuration.KnownDirectories.AppDir,
|
|
Configuration.KnownDirectories.MyDocs,
|
|
Configuration.KnownDirectories.MyMusic,
|
|
},
|
|
Configuration.KnownDirectories.UserProfile,
|
|
"Books");
|
|
booksSelectControl.SelectDirectory(config.Books?.PathWithoutPrefix ?? "");
|
|
|
|
saveEpisodesToSeriesFolderCbox.Checked = config.SavePodcastsToParentFolder;
|
|
overwriteExistingCbox.Checked = config.OverwriteExisting;
|
|
checkForUpgradesCbox.Checked = config.CheckForUpgradesAtStartup;
|
|
gridScaleFactorTbar.Value = scaleFactorToLinearRange(config.GridScaleFactor);
|
|
gridFontScaleFactorTbar.Value = scaleFactorToLinearRange(config.GridFontScaleFactor);
|
|
|
|
Load_TokenStorage(config);
|
|
}
|
|
|
|
private void Load_TokenStorage(Configuration config)
|
|
{
|
|
initialTokenStorageMethod = config.TokenStorageMethod;
|
|
osSecretStoreAvailable = IdentityTokenStorageWiring.IsOsSecretStoreAvailable(out var unavailableReason);
|
|
|
|
encryptTokensCbox.Text = TokenStorageSettingsUi.CheckboxText;
|
|
plaintextTokenWarningLbl.Text = TokenStorageSettingsUi.PlaintextWarningText;
|
|
exportMasterKeyBtn.Text = TokenStorageSettingsUi.ExportButtonText;
|
|
updateExistingTokensBtn.Text = TokenStorageSettingsUi.ConvertButtonText;
|
|
toolTip.SetToolTip(exportMasterKeyBtn, TokenStorageSettingsUi.ExportButtonToolTip);
|
|
toolTip.SetToolTip(updateExistingTokensBtn, TokenStorageSettingsUi.ConvertButtonToolTip);
|
|
|
|
if (!osSecretStoreAvailable)
|
|
{
|
|
osSecretStoreUnavailableLbl.Text = TokenStorageSettingsUi.OsStoreUnavailableMessage(unavailableReason);
|
|
osSecretStoreUnavailableLbl.Visible = true;
|
|
encryptTokensCbox.Checked = false;
|
|
encryptTokensCbox.Enabled = false;
|
|
exportMasterKeyBtn.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
osSecretStoreUnavailableLbl.Visible = false;
|
|
encryptTokensCbox.Enabled = true;
|
|
exportMasterKeyBtn.Enabled = true;
|
|
encryptTokensCbox.Checked = TokenStorageSettingsUi.CheckboxFromMethod(config.TokenStorageMethod);
|
|
}
|
|
|
|
RefreshTokenStorageUiState();
|
|
}
|
|
|
|
private TokenStorageMethod SelectedTokenStorageMethod
|
|
=> TokenStorageSettingsUi.MethodFromCheckbox(encryptTokensCbox.Checked);
|
|
|
|
private void RefreshTokenStorageUiState()
|
|
{
|
|
var method = SelectedTokenStorageMethod;
|
|
plaintextTokenWarningLbl.Visible = osSecretStoreAvailable && method == TokenStorageMethod.Plaintext;
|
|
|
|
var alignment = AccountTokenStorage.GetAccountsAlignment(method);
|
|
updateExistingTokensBtn.Enabled = TokenStorageSettingsUi.IsConvertButtonEnabled(alignment);
|
|
}
|
|
|
|
private void encryptTokensCbox_CheckedChanged(object? sender, EventArgs e)
|
|
=> RefreshTokenStorageUiState();
|
|
|
|
private async void exportMasterKeyBtn_Click(object? sender, EventArgs e)
|
|
{
|
|
if (!await TokenStorageSettingsUi.ConfirmExportMasterKeyAsync(this))
|
|
return;
|
|
|
|
using var dialog = new SaveFileDialog
|
|
{
|
|
Title = TokenStorageSettingsUi.ExportConfirmCaption,
|
|
FileName = IdentityTokenStorageWiring.DefaultMasterKeyFileName,
|
|
Filter = "Master key (*.key)|*.key|All files (*.*)|*.*",
|
|
OverwritePrompt = true
|
|
};
|
|
|
|
if (dialog.ShowDialog(this) != DialogResult.OK)
|
|
return;
|
|
|
|
await TokenStorageSettingsUi.ExportMasterKeyToFileAsync(this, dialog.FileName);
|
|
}
|
|
|
|
private async void updateExistingTokensBtn_Click(object? sender, EventArgs e)
|
|
{
|
|
var converted = await TokenStorageSettingsUi.ConfirmAndConvertAsync(this, SelectedTokenStorageMethod);
|
|
if (converted)
|
|
RefreshTokenStorageUiState();
|
|
}
|
|
|
|
private async Task<bool> Save_Important(Configuration config)
|
|
{
|
|
var newBooks = booksSelectControl.SelectedDirectory;
|
|
|
|
#region validation
|
|
static void validationError(string text, string caption)
|
|
=> MessageBox.Show(text, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
if (string.IsNullOrWhiteSpace(newBooks))
|
|
{
|
|
validationError("Cannot set Books Location to blank", "Location is blank");
|
|
return false;
|
|
}
|
|
LongPath lonNewBooks = newBooks;
|
|
if (!Directory.Exists(lonNewBooks))
|
|
{
|
|
try
|
|
{
|
|
Directory.CreateDirectory(lonNewBooks);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
validationError($"Error creating Books Location:\r\n{ex.Message}", "Error creating directory");
|
|
return false;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
var selectedTokenMethod = SelectedTokenStorageMethod;
|
|
var tokenDecision = await TokenStorageSettingsUi.PromptOnPreferenceSaveAsync(this, initialTokenStorageMethod, selectedTokenMethod);
|
|
if (tokenDecision == TokenStorageSaveDecision.Abort)
|
|
return false;
|
|
|
|
config.Books = newBooks;
|
|
|
|
{
|
|
var logLevelOld = config.LogLevel;
|
|
var logLevelNew = (loggingLevelCb.SelectedItem as Serilog.Events.LogEventLevel?) ?? Serilog.Events.LogEventLevel.Information;
|
|
|
|
config.LogLevel = logLevelNew;
|
|
|
|
// only warn if changed during this time. don't want to warn every time user happens to change settings while level is verbose
|
|
if (logLevelOld != logLevelNew)
|
|
MessageBoxLib.VerboseLoggingWarning_ShowIfTrue();
|
|
}
|
|
|
|
config.SavePodcastsToParentFolder = saveEpisodesToSeriesFolderCbox.Checked;
|
|
config.OverwriteExisting = overwriteExistingCbox.Checked;
|
|
config.CheckForUpgradesAtStartup = checkForUpgradesCbox.Checked;
|
|
|
|
config.CreationTime = (creationTimeCb.SelectedItem as EnumDisplay<Configuration.DateTimeSource>)?.Value ?? Configuration.DateTimeSource.File;
|
|
config.LastWriteTime = (lastWriteTimeCb.SelectedItem as EnumDisplay<Configuration.DateTimeSource>)?.Value ?? Configuration.DateTimeSource.File;
|
|
config.ThemeVariant = (themeCb.SelectedItem as EnumDisplay<Configuration.Theme>)?.Value ?? Configuration.Theme.System;
|
|
config.TokenStorageMethod = selectedTokenMethod;
|
|
|
|
if (tokenDecision == TokenStorageSaveDecision.SavePreferenceAndConvert)
|
|
{
|
|
var converted = await TokenStorageSettingsUi.RunConversionAsync(this, selectedTokenMethod);
|
|
if (!converted)
|
|
return false;
|
|
}
|
|
|
|
initialTokenStorageMethod = selectedTokenMethod;
|
|
RefreshTokenStorageUiState();
|
|
return true;
|
|
}
|
|
|
|
private static int scaleFactorToLinearRange(float scaleFactor)
|
|
=> (int)float.Round(100 * MathF.Log2(scaleFactor));
|
|
private static float linearRangeToScaleFactor(int value)
|
|
=> MathF.Pow(2, value / 100f);
|
|
|
|
private void applyDisplaySettingsBtn_Click(object sender, EventArgs e)
|
|
{
|
|
config.GridFontScaleFactor = linearRangeToScaleFactor(gridFontScaleFactorTbar.Value);
|
|
config.GridScaleFactor = linearRangeToScaleFactor(gridScaleFactorTbar.Value);
|
|
}
|
|
|
|
private void themeCb_SelectedIndexChanged(object? sender, EventArgs e)
|
|
{
|
|
var selected = themeCb.SelectedItem as EnumDisplay<Configuration.Theme>;
|
|
if (selected != null)
|
|
{
|
|
themeVariant = selected.Value;
|
|
themeLbl.Visible = themeVariant != initialThemeVariant;
|
|
}
|
|
}
|
|
}
|