diff --git a/Source/AppScaffolding/AppScaffolding.csproj b/Source/AppScaffolding/AppScaffolding.csproj
index 9c1b8d7a..2dfce40e 100644
--- a/Source/AppScaffolding/AppScaffolding.csproj
+++ b/Source/AppScaffolding/AppScaffolding.csproj
@@ -11,12 +11,6 @@
-
-
- $(DefineConstants);WINDOWS
- $(DefineConstants);LINUX
- $(DefineConstants);MACOS
-
embedded
diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs
index 56f6e781..3d6d0643 100644
--- a/Source/AppScaffolding/LibationScaffolding.cs
+++ b/Source/AppScaffolding/LibationScaffolding.cs
@@ -14,7 +14,6 @@ using Serilog;
namespace AppScaffolding
{
-
public enum ReleaseIdentifier
{
None,
@@ -26,6 +25,16 @@ namespace AppScaffolding
public static class LibationScaffolding
{
+ public static readonly bool IsWindows;
+ public static readonly bool IsLinux;
+ public static readonly bool IsMacOs;
+ static LibationScaffolding()
+ {
+ IsWindows = OperatingSystem.IsWindows();
+ IsLinux = OperatingSystem.IsLinux();
+ IsMacOs = OperatingSystem.IsMacOS();
+ }
+
public static ReleaseIdentifier ReleaseIdentifier { get; private set; }
public static void SetReleaseIdentifier(ReleaseIdentifier releaseID)
@@ -290,14 +299,11 @@ namespace AppScaffolding
if (System.Diagnostics.Debugger.IsAttached)
mode += " (Debugger attached)";
-#if MACOS
- var os = "MacOS";
-#elif LINUX
- var os = "Linux";
-#else
- var os = "Windows";
-#endif
-
+ string OS
+ = IsLinux ? "Linux"
+ : IsMacOs ? "MacOS"
+ : IsWindows ? "Windows"
+ : "UNKNOWN_OS";
// begin logging session with a form feed
Log.Logger.Information("\r\n\f");
@@ -306,7 +312,7 @@ namespace AppScaffolding
AppName = EntryAssembly.GetName().Name,
Version = BuildVersion.ToString(),
ReleaseIdentifier = ReleaseIdentifier,
- OS = os,
+ OS = OS,
Mode = mode,
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
LogLevel_Debug_Enabled = Log.Logger.IsDebugEnabled(),
diff --git a/Source/HangoverAvalonia/App.axaml b/Source/HangoverAvalonia/App.axaml
new file mode 100644
index 00000000..f4f24946
--- /dev/null
+++ b/Source/HangoverAvalonia/App.axaml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/Source/HangoverAvalonia/App.axaml.cs b/Source/HangoverAvalonia/App.axaml.cs
new file mode 100644
index 00000000..a64b8e22
--- /dev/null
+++ b/Source/HangoverAvalonia/App.axaml.cs
@@ -0,0 +1,29 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+using HangoverAvalonia.ViewModels;
+using HangoverAvalonia.Views;
+
+namespace HangoverAvalonia
+{
+ public partial class App : Application
+ {
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ {
+ desktop.MainWindow = new MainWindow
+ {
+ DataContext = new MainWindowViewModel(),
+ };
+ }
+
+ base.OnFrameworkInitializationCompleted();
+ }
+ }
+}
diff --git a/Source/HangoverAvalonia/Assets/hangover.ico b/Source/HangoverAvalonia/Assets/hangover.ico
new file mode 100644
index 00000000..c29a9b6a
Binary files /dev/null and b/Source/HangoverAvalonia/Assets/hangover.ico differ
diff --git a/Source/HangoverAvalonia/HangoverAvalonia.csproj b/Source/HangoverAvalonia/HangoverAvalonia.csproj
new file mode 100644
index 00000000..fa9d602a
--- /dev/null
+++ b/Source/HangoverAvalonia/HangoverAvalonia.csproj
@@ -0,0 +1,74 @@
+
+
+ WinExe
+ net6.0
+
+ copyused
+ true
+ true
+ Hangover
+ true
+ false
+ false
+
+ true
+
+ true
+ false
+ false
+
+ hangover.ico
+
+
+
+ ..\bin\Avalonia\Debug
+ embedded
+
+
+
+ ..\bin\Avalonia\Release
+ embedded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/HangoverAvalonia/Program.cs b/Source/HangoverAvalonia/Program.cs
new file mode 100644
index 00000000..426b6853
--- /dev/null
+++ b/Source/HangoverAvalonia/Program.cs
@@ -0,0 +1,24 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.ReactiveUI;
+using System;
+
+namespace HangoverAvalonia
+{
+ internal class Program
+ {
+ // Initialization code. Don't use any Avalonia, third-party APIs or any
+ // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
+ // yet and stuff might break.
+ [STAThread]
+ public static void Main(string[] args) => BuildAvaloniaApp()
+ .StartWithClassicDesktopLifetime(args);
+
+ // Avalonia configuration, don't remove; also used by visual designer.
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .LogToTrace()
+ .UseReactiveUI();
+ }
+}
diff --git a/Source/HangoverAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml b/Source/HangoverAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml
new file mode 100644
index 00000000..11791d50
--- /dev/null
+++ b/Source/HangoverAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml
@@ -0,0 +1,17 @@
+
+
+
+
+ Release
+ Any CPU
+ ..\bin\Release\linux-chardonnay
+ FileSystem
+ net6.0
+ linux-x64
+ true
+ false
+ false
+
+
\ No newline at end of file
diff --git a/Source/HangoverAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml b/Source/HangoverAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml
new file mode 100644
index 00000000..b982645c
--- /dev/null
+++ b/Source/HangoverAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml
@@ -0,0 +1,17 @@
+
+
+
+
+ Release
+ Any CPU
+ ..\bin\Release\macos-chardonnay
+ FileSystem
+ net6.0
+ osx-x64
+ true
+ false
+ false
+
+
\ No newline at end of file
diff --git a/Source/HangoverAvalonia/Properties/PublishProfiles/WindowsProfile.pubxml b/Source/HangoverAvalonia/Properties/PublishProfiles/WindowsProfile.pubxml
new file mode 100644
index 00000000..1490c0a5
--- /dev/null
+++ b/Source/HangoverAvalonia/Properties/PublishProfiles/WindowsProfile.pubxml
@@ -0,0 +1,17 @@
+
+
+
+
+ Release
+ Any CPU
+ ..\bin\Release\win-chardonnay
+ FileSystem
+ net6.0
+ win-x64
+ true
+ false
+ false
+
+
\ No newline at end of file
diff --git a/Source/HangoverAvalonia/ViewLocator.cs b/Source/HangoverAvalonia/ViewLocator.cs
new file mode 100644
index 00000000..44467ea7
--- /dev/null
+++ b/Source/HangoverAvalonia/ViewLocator.cs
@@ -0,0 +1,30 @@
+using Avalonia.Controls;
+using Avalonia.Controls.Templates;
+using HangoverAvalonia.ViewModels;
+using System;
+
+namespace HangoverAvalonia
+{
+ public class ViewLocator : IDataTemplate
+ {
+ public IControl Build(object data)
+ {
+ var name = data.GetType().FullName!.Replace("ViewModel", "View");
+ var type = Type.GetType(name);
+
+ if (type != null)
+ {
+ return (Control)Activator.CreateInstance(type)!;
+ }
+ else
+ {
+ return new TextBlock { Text = "Not Found: " + name };
+ }
+ }
+
+ public bool Match(object data)
+ {
+ return data is ViewModelBase;
+ }
+ }
+}
diff --git a/Source/HangoverAvalonia/ViewModels/MainWindowViewModel.cs b/Source/HangoverAvalonia/ViewModels/MainWindowViewModel.cs
new file mode 100644
index 00000000..607e3ddb
--- /dev/null
+++ b/Source/HangoverAvalonia/ViewModels/MainWindowViewModel.cs
@@ -0,0 +1,150 @@
+using ApplicationServices;
+using AppScaffolding;
+using Microsoft.EntityFrameworkCore;
+using ReactiveUI;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace HangoverAvalonia.ViewModels
+{
+ public class MainWindowViewModel : ViewModelBase
+ {
+ private string dbFile;
+ private string _databaseFileText;
+ private bool _databaseFound;
+ private string _sqlResults;
+ public string DatabaseFileText { get => _databaseFileText; set => this.RaiseAndSetIfChanged(ref _databaseFileText, value); }
+ public string SqlQuery { get; set; }
+ public bool DatabaseFound { get => _databaseFound; set => this.RaiseAndSetIfChanged(ref _databaseFound, value); }
+ public string SqlResults { get => _sqlResults; set => this.RaiseAndSetIfChanged(ref _sqlResults, value); }
+
+ public MainWindowViewModel()
+ {
+ dbFile = UNSAFE_MigrationHelper.DatabaseFile;
+ if (dbFile is null)
+ {
+ DatabaseFileText = $"Database file not found";
+ DatabaseFound = false;
+ return;
+ }
+
+ DatabaseFileText = $"Database file: {UNSAFE_MigrationHelper.DatabaseFile ?? "not found"}";
+
+ DatabaseFound = UNSAFE_MigrationHelper.DatabaseFile is not null;
+ }
+
+ public void ExecuteQuery()
+ {
+ ensureBackup();
+
+ SqlResults = string.Empty;
+
+ try
+ {
+ var sql = SqlQuery.Trim();
+
+ #region // explanation
+ // Routing statements to non-query is a convenience.
+ // I went down the rabbit hole of full parsing and it's more trouble than it's worth. The parsing is easy due to available libraries. The edge cases of what to do next got too complex for slight gains.
+ // It's also not useful to take the extra effort to separate non-queries which don't return a row count. Eg: alter table, drop table
+ // My half-assed solution here won't even catch simple mistakes like this -- and that's ok
+ // -- line 1 is a comment
+ // delete from foo
+ #endregion
+ var lower = sql.ToLower();
+ if (lower.StartsWith("update") || lower.StartsWith("insert") || lower.StartsWith("delete"))
+ nonQuery(sql);
+ else
+ query(sql);
+ }
+ catch (Exception ex)
+ {
+ SqlResults = $"{ex.Message}\r\n{ex.StackTrace}";
+ }
+ finally
+ {
+ deleteUnneededBackups();
+ }
+ }
+
+ private string dbBackup;
+ private DateTime dbFileLastModified;
+
+ private void ensureBackup()
+ {
+ if (dbBackup is not null)
+ return;
+
+ dbFileLastModified = File.GetLastWriteTimeUtc(dbFile);
+
+ dbBackup
+ = Path.ChangeExtension(dbFile, "").TrimEnd('.')
+ + $"_backup_{DateTime.UtcNow:O}".Replace(':', '-').Replace('.', '-')
+ + Path.GetExtension(dbFile);
+ File.Copy(dbFile, dbBackup);
+ }
+
+ private void deleteUnneededBackups()
+ {
+ var newLastModified = File.GetLastWriteTimeUtc(dbFile);
+ if (dbFileLastModified == newLastModified)
+ {
+ File.Delete(dbBackup);
+ dbBackup = null;
+ }
+ }
+
+ void query(string sql)
+ {
+ // ef doesn't support truly generic queries. have to drop down to ado.net
+ using var context = DbContexts.GetContext();
+ using var conn = context.Database.GetDbConnection();
+ conn.Open();
+ using var cmd = conn.CreateCommand();
+ cmd.CommandText = sql;
+
+ var reader = cmd.ExecuteReader();
+ var results = 0;
+ var builder = new StringBuilder();
+ var lines = 0;
+ while (reader.Read())
+ {
+ results++;
+
+ for (var i = 0; i < reader.FieldCount; i++)
+ builder.Append(reader.GetValue(i) + "\t");
+ builder.AppendLine();
+
+ lines++;
+ if (lines % 10 == 0)
+ {
+ SqlResults += builder.ToString();
+ builder.Clear();
+ }
+ }
+
+ SqlResults += builder.ToString();
+ builder.Clear();
+
+ if (results == 0)
+ SqlResults = "[no results]";
+ else
+ {
+ SqlResults += $"\r\n{results} result";
+ if (results != 1) SqlResults += "s";
+ }
+ }
+
+ void nonQuery(string sql)
+ {
+ using var context = DbContexts.GetContext();
+ var results = context.Database.ExecuteSqlRaw(sql);
+
+ SqlResults += $"{results} record";
+ if (results != 1) SqlResults += "s";
+ SqlResults += " affected";
+ }
+ }
+}
diff --git a/Source/HangoverAvalonia/ViewModels/ViewModelBase.cs b/Source/HangoverAvalonia/ViewModels/ViewModelBase.cs
new file mode 100644
index 00000000..50908ee3
--- /dev/null
+++ b/Source/HangoverAvalonia/ViewModels/ViewModelBase.cs
@@ -0,0 +1,11 @@
+using ReactiveUI;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HangoverAvalonia.ViewModels
+{
+ public class ViewModelBase : ReactiveObject
+ {
+ }
+}
diff --git a/Source/HangoverAvalonia/Views/MainWindow.axaml b/Source/HangoverAvalonia/Views/MainWindow.axaml
new file mode 100644
index 00000000..b32eb8de
--- /dev/null
+++ b/Source/HangoverAvalonia/Views/MainWindow.axaml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Database
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Command Line Interface
+
+
+
+
diff --git a/Source/HangoverAvalonia/Views/MainWindow.axaml.cs b/Source/HangoverAvalonia/Views/MainWindow.axaml.cs
new file mode 100644
index 00000000..60499471
--- /dev/null
+++ b/Source/HangoverAvalonia/Views/MainWindow.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia.Controls;
+using HangoverAvalonia.ViewModels;
+
+namespace HangoverAvalonia.Views
+{
+ public partial class MainWindow : Window
+ {
+ MainWindowViewModel _viewModel => DataContext as MainWindowViewModel;
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ public void Execute_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
+ {
+ _viewModel.ExecuteQuery();
+ }
+ }
+}
diff --git a/Source/HangoverAvalonia/hangover.ico b/Source/HangoverAvalonia/hangover.ico
new file mode 100644
index 00000000..c29a9b6a
Binary files /dev/null and b/Source/HangoverAvalonia/hangover.ico differ
diff --git a/Source/LibationAvalonia/App.axaml.cs b/Source/LibationAvalonia/App.axaml.cs
index a3f0b2a4..c32d82f4 100644
--- a/Source/LibationAvalonia/App.axaml.cs
+++ b/Source/LibationAvalonia/App.axaml.cs
@@ -17,16 +17,6 @@ namespace LibationAvalonia
{
public class App : Application
{
- public static readonly bool IsWindows;
- public static readonly bool IsLinux;
- public static readonly bool IsMacOs;
- static App()
- {
- IsWindows = OperatingSystem.IsWindows();
- IsLinux = OperatingSystem.IsLinux();
- IsMacOs = OperatingSystem.IsMacOS();
- }
-
public static IBrush ProcessQueueBookFailedBrush { get; private set; }
public static IBrush ProcessQueueBookCompletedBrush { get; private set; }
public static IBrush ProcessQueueBookCancelledBrush { get; private set; }
@@ -41,14 +31,14 @@ namespace LibationAvalonia
public static bool GoToFile(string path)
- => IsWindows ? Go.To.File(path)
+ => AppScaffolding.LibationScaffolding.IsWindows ? Go.To.File(path)
: GoToFolder(path is null ? string.Empty : Path.GetDirectoryName(path));
public static bool GoToFolder(string path)
{
- if (IsWindows)
+ if (AppScaffolding.LibationScaffolding.IsWindows)
return Go.To.Folder(path);
- else if (IsLinux)
+ else if (AppScaffolding.LibationScaffolding.IsLinux)
{
var startInfo = new System.Diagnostics.ProcessStartInfo()
{
@@ -82,7 +72,6 @@ namespace LibationAvalonia
var SEGOEUI = new Typeface(new FontFamily(new Uri("avares://Libation/Assets/WINGDING.TTF"), "SEGOEUI_Local"));
var gtf = FontManager.Current.GetOrAddGlyphTypeface(SEGOEUI);
-
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
if (SetupRequired)
@@ -125,28 +114,21 @@ namespace LibationAvalonia
// all returns should be preceded by either:
// - if config.LibationSettingsAreValid
// - error message, Exit()
-
- if ((!setupDialog.IsNewUser
- && !setupDialog.IsReturningUser) ||
- !await RunInstall(setupDialog))
+ if (setupDialog.IsNewUser)
+ {
+ setupDialog.Config.SetLibationFiles(Configuration.UserProfile);
+ ShowSettingsWindow(desktop, setupDialog.Config, OnSettingsCompleted);
+ }
+ else if (setupDialog.IsReturningUser)
+ {
+ ShowLibationFilesDialog(desktop, setupDialog.Config, OnLibationFilesCompleted);
+ }
+ else
{
await CancelInstallation();
return;
}
-
- // most migrations go in here
- AppScaffolding.LibationScaffolding.RunPostConfigMigrations(setupDialog.Config);
-
- await MessageBox.VerboseLoggingWarning_ShowIfTrue();
-
-#if !DEBUG
- //AutoUpdater.NET only works for WinForms or WPF application projects.
- //checkForUpdate();
-#endif
- // logging is init'd here
- AppScaffolding.LibationScaffolding.RunPostMigrationScaffolding(setupDialog.Config);
-
}
catch (Exception ex)
{
@@ -162,32 +144,83 @@ namespace LibationAvalonia
}
return;
}
-
- LibraryTask = Task.Run(() => DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
- AudibleUtilities.AudibleApiStorage.EnsureAccountsSettingsFileExists();
- ShowMainWindow(desktop);
}
- private static async Task RunInstall(SetupDialog setupDialog)
+ private async Task RunMigrationsAsync(Configuration config)
{
- var config = setupDialog.Config;
+ // most migrations go in here
+ AppScaffolding.LibationScaffolding.RunPostConfigMigrations(config);
- if (setupDialog.IsNewUser)
+ await MessageBox.VerboseLoggingWarning_ShowIfTrue();
+
+ // logging is init'd here
+ AppScaffolding.LibationScaffolding.RunPostMigrationScaffolding(config);
+ }
+
+ private void ShowSettingsWindow(IClassicDesktopStyleApplicationLifetime desktop, Configuration config, Action OnClose)
+ {
+ config.Books ??= Path.Combine(Configuration.UserProfile, "Books");
+
+ AppScaffolding.LibationScaffolding.PopulateMissingConfigValues(config);
+
+ var settingsDialog = new SettingsDialog();
+ desktop.MainWindow = settingsDialog;
+ settingsDialog.RestoreSizeAndLocation(Configuration.Instance);
+ settingsDialog.Show();
+
+ void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
- config.SetLibationFiles(Configuration.UserProfile);
+ settingsDialog.Closing -= WindowClosing;
+ e.Cancel = true;
+ OnClose?.Invoke(desktop, settingsDialog, config);
}
- else if (setupDialog.IsReturningUser)
+ settingsDialog.Closing += WindowClosing;
+ }
+
+ private async void OnSettingsCompleted(IClassicDesktopStyleApplicationLifetime desktop, SettingsDialog settingsDialog, Configuration config)
+ {
+ if (config.LibationSettingsAreValid)
{
+ await RunMigrationsAsync(config);
+ LibraryTask = Task.Run(() => DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
+ AudibleUtilities.AudibleApiStorage.EnsureAccountsSettingsFileExists();
+ ShowMainWindow(desktop);
+ }
+ else
+ await CancelInstallation();
- var libationFilesDialog = new LibationFilesDialog();
+ settingsDialog.Close();
+ }
- if (await libationFilesDialog.ShowDialog(setupDialog) != DialogResult.OK)
- return false;
- config.SetLibationFiles(libationFilesDialog.SelectedDirectory);
- if (config.LibationSettingsAreValid)
- return true;
+ private void ShowLibationFilesDialog(IClassicDesktopStyleApplicationLifetime desktop, Configuration config, Action OnClose)
+ {
+ var libationFilesDialog = new LibationFilesDialog();
+ desktop.MainWindow = libationFilesDialog;
+ libationFilesDialog.Show();
+ void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ libationFilesDialog.Closing -= WindowClosing;
+ e.Cancel = true;
+ OnClose?.Invoke(desktop, libationFilesDialog, config);
+ }
+ libationFilesDialog.Closing += WindowClosing;
+ }
+
+ private async void OnLibationFilesCompleted(IClassicDesktopStyleApplicationLifetime desktop, LibationFilesDialog libationFilesDialog, Configuration config)
+ {
+ config.SetLibationFiles(libationFilesDialog.SelectedDirectory);
+ if (config.LibationSettingsAreValid)
+ {
+ await RunMigrationsAsync(config);
+
+ LibraryTask = Task.Run(() => DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
+ AudibleUtilities.AudibleApiStorage.EnsureAccountsSettingsFileExists();
+ ShowMainWindow(desktop);
+ }
+ else
+ {
// path did not result in valid settings
var continueResult = await MessageBox.Show(
$"No valid settings were found at this location.\r\nWould you like to create a new install settings in this folder?\r\n\r\n{libationFilesDialog.SelectedDirectory}",
@@ -195,17 +228,13 @@ namespace LibationAvalonia
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
- if (continueResult != DialogResult.Yes)
- return false;
+ if (continueResult == DialogResult.Yes)
+ ShowSettingsWindow(desktop, config, OnSettingsCompleted);
+ else
+ await CancelInstallation();
+
}
-
- // INIT DEFAULT SETTINGS
- // if 'new user' was clicked, or if 'returning user' chose new install: show basic settings dialog
- config.Books ??= Path.Combine(Configuration.UserProfile, "Books");
-
- AppScaffolding.LibationScaffolding.PopulateMissingConfigValues(config);
- return await new SettingsDialog().ShowDialog(setupDialog) == DialogResult.OK
- && config.LibationSettingsAreValid;
+ libationFilesDialog.Close();
}
static async Task CancelInstallation()
diff --git a/Source/LibationAvalonia/Dialogs/ImageDisplayDialog.axaml.cs b/Source/LibationAvalonia/Dialogs/ImageDisplayDialog.axaml.cs
index 9bd7f398..049f3203 100644
--- a/Source/LibationAvalonia/Dialogs/ImageDisplayDialog.axaml.cs
+++ b/Source/LibationAvalonia/Dialogs/ImageDisplayDialog.axaml.cs
@@ -51,7 +51,7 @@ namespace LibationAvalonia.Dialogs
saveFileDialog.Filters.Add(new FileDialogFilter { Name = "Jpeg", Extensions = new System.Collections.Generic.List() { "jpg" } });
saveFileDialog.InitialFileName = PictureFileName;
saveFileDialog.Directory
- = !App.IsWindows ? null
+ = !AppScaffolding.LibationScaffolding.IsWindows ? null
: Directory.Exists(BookSaveDirectory) ? BookSaveDirectory
: Path.GetDirectoryName(BookSaveDirectory);
diff --git a/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml b/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml
index 0ddabd5e..b394e510 100644
--- a/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml
+++ b/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml
@@ -7,6 +7,7 @@
MinWidth="800" MaxWidth="800"
x:Class="LibationAvalonia.Dialogs.LibationFilesDialog"
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
+ WindowStartupLocation="CenterScreen"
Title="Book Details"
Icon="/Assets/libation.ico">
diff --git a/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml.cs b/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml.cs
index a1ba044f..bdc73730 100644
--- a/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml.cs
+++ b/Source/LibationAvalonia/Dialogs/LibationFilesDialog.axaml.cs
@@ -23,6 +23,7 @@ namespace LibationAvalonia.Dialogs
}
private DirSelectOptions dirSelectOptions;
public string SelectedDirectory => dirSelectOptions.Directory;
+ public DialogResult DialogResult { get; private set; }
public LibationFilesDialog()
{
InitializeComponent();
@@ -44,7 +45,8 @@ namespace LibationAvalonia.Dialogs
return;
}
- Close(DialogResult.OK);
+ DialogResult = DialogResult.OK;
+ Close(DialogResult);
}
private void InitializeComponent()
diff --git a/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml b/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml
index fd4bf1a9..823234de 100644
--- a/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml
+++ b/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml
@@ -495,6 +495,7 @@
AppScaffolding.LibationScaffolding.IsLinux || AppScaffolding.LibationScaffolding.IsWindows;
+
public AudioSettings(Configuration config)
{
LoadSettings(config);
diff --git a/Source/LibationAvalonia/FormSaveExtension.cs b/Source/LibationAvalonia/FormSaveExtension.cs
index 3b041e92..352b9808 100644
--- a/Source/LibationAvalonia/FormSaveExtension.cs
+++ b/Source/LibationAvalonia/FormSaveExtension.cs
@@ -113,7 +113,7 @@ namespace LibationAvalonia
public static void HideMinMaxBtns(this Window form)
{
- if (Design.IsDesignMode || !App.IsWindows)
+ if (Design.IsDesignMode || !AppScaffolding.LibationScaffolding.IsWindows)
return;
var handle = form.PlatformImpl.Handle.Handle;
var currentStyle = GetWindowLong(handle, GWL_STYLE);
diff --git a/Source/LibationAvalonia/Program.cs b/Source/LibationAvalonia/Program.cs
index f0208cfe..a42878ba 100644
--- a/Source/LibationAvalonia/Program.cs
+++ b/Source/LibationAvalonia/Program.cs
@@ -30,11 +30,11 @@ namespace LibationAvalonia
var classicLifetimeTask = Task.Run(() => new ClassicDesktopStyleApplicationLifetime());
var appBuilderTask = Task.Run(BuildAvaloniaApp);
- if (App.IsWindows)
+ if (AppScaffolding.LibationScaffolding.IsWindows)
AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.WindowsAvalonia);
- else if (App.IsLinux)
+ else if (AppScaffolding.LibationScaffolding.IsLinux)
AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.LinuxAvalonia);
- else if (App.IsMacOs)
+ else if (AppScaffolding.LibationScaffolding.IsMacOs)
AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.MacOSAvalonia);
else return;
diff --git a/Source/LibationAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml b/Source/LibationAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml
index a846a327..11791d50 100644
--- a/Source/LibationAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml
+++ b/Source/LibationAvalonia/Properties/PublishProfiles/LinuxProfile.pubxml
@@ -3,14 +3,15 @@
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
-
- Release
- Any CPU
- ..\bin\Release\linux-chardonnay
- FileSystem
- net6.0
- linux-x64
- false
- false
-
+
+ Release
+ Any CPU
+ ..\bin\Release\linux-chardonnay
+ FileSystem
+ net6.0
+ linux-x64
+ true
+ false
+ false
+
\ No newline at end of file
diff --git a/Source/LibationAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml b/Source/LibationAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml
index 5d1e98f9..51602bd3 100644
--- a/Source/LibationAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml
+++ b/Source/LibationAvalonia/Properties/PublishProfiles/MacOSProfile.pubxml
@@ -3,14 +3,15 @@
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
-
- Release
- Any CPU
- ..\bin\Release\macos-chardonnay
- FileSystem
- net6.0
- osx-x64
- false
- false
-
+
+ Release
+ Any CPU
+ ..\bin\Release\macos-chardonnay
+ FileSystem
+ net6.0
+ osx-x64
+ true
+ false
+ false
+
\ No newline at end of file
diff --git a/Source/LibationAvalonia/README.md b/Source/LibationAvalonia/README.md
index 2b916b64..12ae698b 100644
--- a/Source/LibationAvalonia/README.md
+++ b/Source/LibationAvalonia/README.md
@@ -7,51 +7,7 @@ Some limitations of the linux release are:
- The "Hangover" app for debugging is not yet available.
## Dependencies
-### Dotnet Runtime
-You must install the dotnet 6.0 runtime on your machine.
-First, add the Microsoft package signing key to your list of trusted keys and add the package repository.
-
-
- Ubuntu 22.04
-
- ```console
- wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- sudo dpkg -i packages-microsoft-prod.deb
- rm packages-microsoft-prod.deb
- ```
-
-
-
- Ubuntu 21.10
-
- ```console
- wget https://packages.microsoft.com/config/ubuntu/21.10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- sudo dpkg -i packages-microsoft-prod.deb
- rm packages-microsoft-prod.deb
- ```
-
-
-
- Ubuntu 20.04
-
- ```console
- wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- sudo dpkg -i packages-microsoft-prod.deb
- rm packages-microsoft-prod.deb
- ```
-
-
-For other distributions, see [Microsoft's instructions for installing .NET on Linux](https://docs.microsoft.com/en-us/dotnet/core/install/linux).
-
-Then install the dotnet 6.0 runtime
-
-```console
-sudo apt-get update; \
- sudo apt-get install -y apt-transport-https && \
- sudo apt-get update && \
- sudo apt-get install -y dotnet-runtime-6.0
-```
### FFMpeg (Optional)
If you want to convert your audiobooks to mp3, install FFMpeg using the following command:
@@ -67,8 +23,7 @@ Download the most recent linux-64 binaries zip file and save it as `libation-lin
install-libation.sh
```BASH
- #!/bin/bash
-
+ #!/bin/bash
FILE=$1
@@ -77,10 +32,10 @@ Download the most recent linux-64 binaries zip file and save it as `libation-lin
exit
fi
-if [ "$EUID" -ne 0 ]
- then echo "Please run as root"
- exit
-fi
+ if [[ "$EUID" -ne 0 ]]
+ then echo "Please run as root"
+ exit
+ fi
if [ ! -f "$FILE" ]
then echo "The file \"$FILE\" does not exist."
@@ -99,12 +54,13 @@ fi
exit
fi
-
sudo -u $SUDO_USER chmod +700 ${FOLDER}/Libation
+ sudo -u $SUDO_USER chmod +700 ${FOLDER}/Hangover
sudo -u $SUDO_USER chmod +700 ${FOLDER}/LibationCli
#Remove previous installation program files and sym link
rm /usr/bin/Libation
+ rm /usr/bin/Hangover
rm /usr/bin/LibationCli
rm /usr/bin/libationcli
rm /usr/lib/libation -r
@@ -117,11 +73,11 @@ fi
chmod +666 /usr/share/icons/hicolor/scalable/apps/libation.svg
gtk-update-icon-cache -f /usr/share/icons/hicolor/
ln -s /usr/lib/libation/Libation /usr/bin/Libation
+ ln -s /usr/lib/libation/Hangover /usr/bin/Hangover
ln -s /usr/lib/libation/LibationCli /usr/bin/LibationCli
ln -s /usr/lib/libation/LibationCli /usr/bin/libationcli
echo "Done!"
-
```
diff --git a/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs b/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs
index f1656ae7..5a8b75d4 100644
--- a/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs
+++ b/Source/LibationAvalonia/ViewModels/MainWindowViewModel.cs
@@ -19,6 +19,7 @@ namespace LibationAvalonia.ViewModels
private int _visibleCount = 1;
private LibraryCommands.LibraryStats _libraryStats;
private int _visibleNotLiberated = 1;
+ public bool IsMp3Supported => AppScaffolding.LibationScaffolding.IsLinux || AppScaffolding.LibationScaffolding.IsWindows;
/// The Process Queue's viewmodel
public ProcessQueueViewModel ProcessQueue { get; } = new ProcessQueueViewModel();
diff --git a/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml b/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml
index 3b1f59dc..b53c63e2 100644
--- a/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml
+++ b/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml
@@ -65,7 +65,7 @@
-
+
diff --git a/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml.cs b/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml.cs
index 64d0dced..e6e747ff 100644
--- a/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml.cs
+++ b/Source/LibationAvalonia/Views/MainWindow/MainWindow.axaml.cs
@@ -70,7 +70,7 @@ namespace LibationAvalonia.Views
#if !DEBUG
//This is temporaty until we have a solution for linux/mac so that
//Libation doesn't download a zip every time it runs.
- if (!App.IsWindows)
+ if (!LibationScaffolding.IsWindows)
return;
try
@@ -85,15 +85,15 @@ namespace LibationAvalonia.Views
if (result != DialogResult.Yes)
return;
- if (App.IsWindows)
+ if (LibationScaffolding.IsWindows)
{
runWindowsUpgrader(zipFile);
}
- else if (App.IsLinux)
+ else if (LibationScaffolding.IsLinux)
{
}
- else if (App.IsMacOs)
+ else if (LibationScaffolding.IsMacOs)
{
}
diff --git a/Source/LibationCli/Properties/PublishProfiles/LinuxProfile.pubxml b/Source/LibationCli/Properties/PublishProfiles/LinuxProfile.pubxml
index a846a327..11791d50 100644
--- a/Source/LibationCli/Properties/PublishProfiles/LinuxProfile.pubxml
+++ b/Source/LibationCli/Properties/PublishProfiles/LinuxProfile.pubxml
@@ -3,14 +3,15 @@
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
-
- Release
- Any CPU
- ..\bin\Release\linux-chardonnay
- FileSystem
- net6.0
- linux-x64
- false
- false
-
+
+ Release
+ Any CPU
+ ..\bin\Release\linux-chardonnay
+ FileSystem
+ net6.0
+ linux-x64
+ true
+ false
+ false
+
\ No newline at end of file
diff --git a/Source/LibationCli/Properties/PublishProfiles/MacOSProfile.pubxml b/Source/LibationCli/Properties/PublishProfiles/MacOSProfile.pubxml
index 5d1e98f9..51602bd3 100644
--- a/Source/LibationCli/Properties/PublishProfiles/MacOSProfile.pubxml
+++ b/Source/LibationCli/Properties/PublishProfiles/MacOSProfile.pubxml
@@ -3,14 +3,15 @@
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
-
- Release
- Any CPU
- ..\bin\Release\macos-chardonnay
- FileSystem
- net6.0
- osx-x64
- false
- false
-
+
+ Release
+ Any CPU
+ ..\bin\Release\macos-chardonnay
+ FileSystem
+ net6.0
+ osx-x64
+ true
+ false
+ false
+
\ No newline at end of file
diff --git a/Source/LibationCli/Properties/PublishProfiles/WindowsProfile.pubxml b/Source/LibationCli/Properties/PublishProfiles/WindowsProfile.pubxml
index 1490c0a5..24f5783e 100644
--- a/Source/LibationCli/Properties/PublishProfiles/WindowsProfile.pubxml
+++ b/Source/LibationCli/Properties/PublishProfiles/WindowsProfile.pubxml
@@ -3,15 +3,15 @@
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
-
- Release
- Any CPU
- ..\bin\Release\win-chardonnay
- FileSystem
- net6.0
- win-x64
- true
- false
- false
-
+
+ Release
+ Any CPU
+ ..\bin\Release\win-chardonnay
+ FileSystem
+ net6.0
+ win-x64
+ true
+ false
+ false
+
\ No newline at end of file