Added book details dialog
This commit is contained in:
parent
35f677a0fa
commit
952173d450
55
Source/LibationWinForms/AvaloniaUI/Controls/GroupBox.axaml
Normal file
55
Source/LibationWinForms/AvaloniaUI/Controls/GroupBox.axaml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<ContentControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:controls="clr-namespace:LibationWinForms.AvaloniaUI.Controls"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="LibationWinForms.AvaloniaUI.Controls.GroupBox">
|
||||||
|
|
||||||
|
<Design.DataContext>
|
||||||
|
</Design.DataContext>
|
||||||
|
|
||||||
|
<ContentControl.Styles>
|
||||||
|
<Style Selector="controls|GroupBox Border">
|
||||||
|
<Setter Property="BorderBrush" Value="DarkGray" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="controls|GroupBox">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate>
|
||||||
|
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="7,10,*,Auto">
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
ZIndex="1"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
Grid.Column="1" Margin="8,0,0,0"
|
||||||
|
ColumnDefinitions="Auto,*"
|
||||||
|
VerticalAlignment="Top">
|
||||||
|
<TextBlock
|
||||||
|
Padding="4,0,4,0"
|
||||||
|
Background="{StaticResource SystemAltHighColor}"
|
||||||
|
Text="{TemplateBinding Label}"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
Margin="8,0,8,5"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Content="{TemplateBinding Content}"/>
|
||||||
|
|
||||||
|
<Border
|
||||||
|
BorderBrush="DarkGray"
|
||||||
|
BorderThickness="{TemplateBinding BorderWidth}"
|
||||||
|
CornerRadius="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="3"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.RowSpan="3"/>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ContentControl.Styles>
|
||||||
|
</ContentControl>
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace LibationWinForms.AvaloniaUI.Controls
|
||||||
|
{
|
||||||
|
public partial class GroupBox : ContentControl
|
||||||
|
{
|
||||||
|
|
||||||
|
public static readonly StyledProperty<Thickness> BorderWidthProperty =
|
||||||
|
AvaloniaProperty.Register<GroupBox, Thickness>(nameof(BorderWidth));
|
||||||
|
|
||||||
|
public static readonly StyledProperty<string> LabelProperty =
|
||||||
|
AvaloniaProperty.Register<GroupBox, string>(nameof(Label));
|
||||||
|
public GroupBox()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
BorderWidth = new Thickness(3);
|
||||||
|
Label = "This is a groupbox label";
|
||||||
|
}
|
||||||
|
public Thickness BorderWidth
|
||||||
|
{
|
||||||
|
get { return GetValue(BorderWidthProperty); }
|
||||||
|
set { SetValue(BorderWidthProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Label
|
||||||
|
{
|
||||||
|
get { return GetValue(LabelProperty); }
|
||||||
|
set { SetValue(LabelProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,7 +24,7 @@ namespace LibationWinForms.AvaloniaUI
|
|||||||
|
|
||||||
public static void RestoreSizeAndLocation(this Window form, Configuration config)
|
public static void RestoreSizeAndLocation(this Window form, Configuration config)
|
||||||
{
|
{
|
||||||
FormSizeAndPosition savedState = config.GetNonString<FormSizeAndPosition>(form.Name);
|
FormSizeAndPosition savedState = config.GetNonString<FormSizeAndPosition>(form.GetType().Name);
|
||||||
|
|
||||||
if (savedState is null)
|
if (savedState is null)
|
||||||
return;
|
return;
|
||||||
@ -79,7 +79,7 @@ namespace LibationWinForms.AvaloniaUI
|
|||||||
saveState.Width = (int)form.Bounds.Size.Width;
|
saveState.Width = (int)form.Bounds.Size.Width;
|
||||||
saveState.Height = (int)form.Bounds.Size.Height;
|
saveState.Height = (int)form.Bounds.Size.Height;
|
||||||
|
|
||||||
config.SetObject(form.Name, saveState);
|
config.SetObject(form.GetType().Name, saveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FormSizeAndPosition
|
class FormSizeAndPosition
|
||||||
|
|||||||
@ -201,7 +201,7 @@ namespace LibationWinForms.AvaloniaUI
|
|||||||
return await ShowCore(owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
|
return await ShowCore(owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DialogResult> ShowConfirmationDialog(Window owner, IEnumerable<LibraryBook> libraryBooks, string format, string title)
|
public static async Task<DialogResult> ShowConfirmationDialog(Window owner, IEnumerable<LibraryBook> libraryBooks, string format, string title, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1)
|
||||||
{
|
{
|
||||||
if (libraryBooks is null || !libraryBooks.Any())
|
if (libraryBooks is null || !libraryBooks.Any())
|
||||||
return DialogResult.Cancel;
|
return DialogResult.Cancel;
|
||||||
@ -221,7 +221,7 @@ namespace LibationWinForms.AvaloniaUI
|
|||||||
title,
|
title,
|
||||||
MessageBoxButtons.YesNo,
|
MessageBoxButtons.YesNo,
|
||||||
MessageBoxIcon.Question,
|
MessageBoxIcon.Question,
|
||||||
MessageBoxDefaultButton.Button1);
|
defaultButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<DialogResult> ShowCore(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
|
private static async Task<DialogResult> ShowCore(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
|
||||||
|
|||||||
@ -28,60 +28,6 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
Queue.QueuededCountChanged += Queue_QueuededCountChanged;
|
Queue.QueuededCountChanged += Queue_QueuededCountChanged;
|
||||||
Queue.CompletedCountChanged += Queue_CompletedCountChanged;
|
Queue.CompletedCountChanged += Queue_CompletedCountChanged;
|
||||||
Logger = ProcessQueue.LogMe.RegisterForm(this);
|
Logger = ProcessQueue.LogMe.RegisterForm(this);
|
||||||
|
|
||||||
#region Design Mode Testing
|
|
||||||
if (Design.IsDesignMode)
|
|
||||||
{
|
|
||||||
using var context = DbContexts.GetContext();
|
|
||||||
var book = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
|
|
||||||
List<ProcessBook2> testList = new()
|
|
||||||
{
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.FailedAbort,
|
|
||||||
Status = ProcessBookStatus.Failed,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.FailedSkip,
|
|
||||||
Status = ProcessBookStatus.Failed,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.FailedRetry,
|
|
||||||
Status = ProcessBookStatus.Failed,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.ValidationFail,
|
|
||||||
Status = ProcessBookStatus.Failed,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.Cancelled,
|
|
||||||
Status = ProcessBookStatus.Cancelled,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.Success,
|
|
||||||
Status = ProcessBookStatus.Completed,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.None,
|
|
||||||
Status = ProcessBookStatus.Working,
|
|
||||||
},
|
|
||||||
new ProcessBook2(book, Logger)
|
|
||||||
{
|
|
||||||
Result = ProcessBookResult.None,
|
|
||||||
Status = ProcessBookStatus.Queued,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
Items.Enqueue(testList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _completedCount;
|
private int _completedCount;
|
||||||
|
|||||||
@ -39,25 +39,10 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
=> GridEntries
|
=> GridEntries
|
||||||
.AllItems()
|
.AllItems()
|
||||||
.BookEntries();
|
.BookEntries();
|
||||||
|
public ProductsDisplayViewModel() { }
|
||||||
public ProductsDisplayViewModel()
|
public ProductsDisplayViewModel(List<GridEntry2> items)
|
||||||
{
|
{
|
||||||
if (Design.IsDesignMode)
|
GridEntries = new GridEntryBindingList2(items);
|
||||||
{
|
|
||||||
using var context = DbContexts.GetContext();
|
|
||||||
List<LibraryBook> sampleEntries = new()
|
|
||||||
{
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017V4IM1G"),
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017V4IWVG"),
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017V4JA2Q"),
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017V4NUPO"),
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017V4NMX4"),
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017V4NOZ0"),
|
|
||||||
context.GetLibraryBook_Flat_NoTracking("B017WJ5ZK6"),
|
|
||||||
};
|
|
||||||
GridEntries = new GridEntryBindingList2(CreateGridEntries(sampleEntries));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Display Functions
|
#region Display Functions
|
||||||
|
|||||||
@ -0,0 +1,130 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="550" d:DesignHeight="450"
|
||||||
|
MinWidth="550" MinHeight="450"
|
||||||
|
Width="650" Height="500"
|
||||||
|
x:Class="LibationWinForms.AvaloniaUI.Views.Dialogs.BookDetailsDialog2"
|
||||||
|
xmlns:controls="clr-namespace:LibationWinForms.AvaloniaUI.Controls"
|
||||||
|
Title="Book Details" Name="BookDetails"
|
||||||
|
Icon="/AvaloniaUI/Assets/libation.ico">
|
||||||
|
|
||||||
|
<Grid RowDefinitions="*,Auto,Auto,Auto">
|
||||||
|
<Grid ColumnDefinitions="Auto,*" Margin="10,10,10,0">
|
||||||
|
<Panel VerticalAlignment="Top" Margin="5" Background="LightGray" Width="80" Height="80" >
|
||||||
|
<Image Grid.Column="0" Width="80" Height="80" Source="{Binding Cover}" />
|
||||||
|
</Panel>
|
||||||
|
|
||||||
|
<TextBox
|
||||||
|
Grid.Column="1"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Margin="5"
|
||||||
|
FontSize="12"
|
||||||
|
Text="{Binding DetailsText}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<controls:GroupBox
|
||||||
|
Label="Edit Tags"
|
||||||
|
Grid.Row="1"
|
||||||
|
BorderWidth="1"
|
||||||
|
Margin="10,0,10,0">
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock FontSize="12" VerticalAlignment="Top">
|
||||||
|
Tags are separated by a space. Each tag can contain letters, numbers, and underscores
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<TextBox Margin="0,5,0,5"
|
||||||
|
MinHeight="25"
|
||||||
|
FontSize="12"
|
||||||
|
Text="{Binding Tags, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</controls:GroupBox>
|
||||||
|
|
||||||
|
<controls:GroupBox
|
||||||
|
Label="Liberated status: Whether the book/pdf has been downloaded"
|
||||||
|
Grid.Row="2"
|
||||||
|
BorderWidth="1"
|
||||||
|
Margin="10,10,10,10">
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
FontSize="12"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="10,10,0,0"
|
||||||
|
Text="To download again next time: change to Not Downloaded
To not download: change to Downloaded" />
|
||||||
|
|
||||||
|
<Grid Margin="0,10,0,5" ColumnDefinitions="Auto,Auto,50,Auto,Auto,*">
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="Book" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="3"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="PDF" />
|
||||||
|
|
||||||
|
<ComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="150"
|
||||||
|
MinHeight="25"
|
||||||
|
Height="25"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
SelectedItem="{Binding BookLiberatedSelectedItem, Mode=TwoWay}"
|
||||||
|
Items="{Binding BookLiberatedItems}">
|
||||||
|
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
FontSize="12"
|
||||||
|
Text="{Binding Text}" />
|
||||||
|
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
<ComboBox
|
||||||
|
IsEnabled="{Binding HasPDF}"
|
||||||
|
Grid.Column="4"
|
||||||
|
MinHeight="25"
|
||||||
|
Height="25"
|
||||||
|
Width="150"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
SelectedItem="{Binding PdfLiberatedSelectedItem, Mode=TwoWay}"
|
||||||
|
Items="{Binding PdfLiberatedItems}">
|
||||||
|
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
FontSize="12"
|
||||||
|
Text="{Binding Text}" />
|
||||||
|
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
|
||||||
|
</ComboBox>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</controls:GroupBox>
|
||||||
|
|
||||||
|
<Grid Grid.Row="3" ColumnDefinitions="*,Auto" Margin="10,0,10,10">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Content="Save"
|
||||||
|
Padding="30,3,30,3"
|
||||||
|
Click="SaveButton_Clicked" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
@ -0,0 +1,157 @@
|
|||||||
|
using ApplicationServices;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using DataLayer;
|
||||||
|
using LibationFileManager;
|
||||||
|
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace LibationWinForms.AvaloniaUI.Views.Dialogs
|
||||||
|
{
|
||||||
|
public partial class BookDetailsDialog2 : Window
|
||||||
|
{
|
||||||
|
private LibraryBook _libraryBook;
|
||||||
|
private BookDetailsDialogViewModel _viewModel;
|
||||||
|
public LibraryBook LibraryBook
|
||||||
|
{
|
||||||
|
get => _libraryBook;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_libraryBook = value;
|
||||||
|
Title = _libraryBook.Book.Title;
|
||||||
|
DataContext = _viewModel = new BookDetailsDialogViewModel(_libraryBook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NewTags => _viewModel.Tags;
|
||||||
|
public LiberatedStatus BookLiberatedStatus => _viewModel.BookLiberatedSelectedItem.Status;
|
||||||
|
public LiberatedStatus? PdfLiberatedStatus => _viewModel.PdfLiberatedSelectedItem?.Status;
|
||||||
|
|
||||||
|
public BookDetailsDialog2()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
#if DEBUG
|
||||||
|
this.AttachDevTools();
|
||||||
|
#endif
|
||||||
|
if (Design.IsDesignMode)
|
||||||
|
{
|
||||||
|
using var context = DbContexts.GetContext();
|
||||||
|
LibraryBook = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public BookDetailsDialog2(LibraryBook libraryBook) :this()
|
||||||
|
{
|
||||||
|
LibraryBook = libraryBook;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveButton_Clicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
LibraryBook.Book.UpdateBook(NewTags, bookStatus: BookLiberatedStatus, pdfStatus: PdfLiberatedStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BookDetailsDialogViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
public class liberatedComboBoxItem
|
||||||
|
{
|
||||||
|
public LiberatedStatus Status { get; set; }
|
||||||
|
public string Text { get; set; }
|
||||||
|
public override string ToString() => Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap Cover { get; set; }
|
||||||
|
public string DetailsText { get; set; }
|
||||||
|
public string Tags { get; set; }
|
||||||
|
|
||||||
|
public bool HasPDF => PdfLiberatedItems?.Count > 0;
|
||||||
|
|
||||||
|
private liberatedComboBoxItem _bookLiberatedSelectedItem;
|
||||||
|
public ObservableCollection<liberatedComboBoxItem> BookLiberatedItems { get; } = new();
|
||||||
|
public List<liberatedComboBoxItem> PdfLiberatedItems { get; } = new();
|
||||||
|
public liberatedComboBoxItem PdfLiberatedSelectedItem { get; set; }
|
||||||
|
|
||||||
|
public liberatedComboBoxItem BookLiberatedSelectedItem
|
||||||
|
{
|
||||||
|
get => _bookLiberatedSelectedItem;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_bookLiberatedSelectedItem = value;
|
||||||
|
if (value?.Status is not LiberatedStatus.Error)
|
||||||
|
{
|
||||||
|
BookLiberatedItems.Remove(BookLiberatedItems.SingleOrDefault(s => s.Status == LiberatedStatus.Error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BookDetailsDialogViewModel(LibraryBook libraryBook)
|
||||||
|
{
|
||||||
|
//init tags
|
||||||
|
Tags = libraryBook.Book.UserDefinedItem.Tags;
|
||||||
|
|
||||||
|
//init cover image
|
||||||
|
var picture = PictureStorage.GetPictureSynchronously(new PictureDefinition(libraryBook.Book.PictureId, PictureSize._80x80));
|
||||||
|
using var ms = new System.IO.MemoryStream(picture);
|
||||||
|
Cover = new Bitmap(ms);
|
||||||
|
|
||||||
|
//init book details
|
||||||
|
DetailsText = @$"
|
||||||
|
Title: {libraryBook.Book.Title}
|
||||||
|
Author(s): {libraryBook.Book.AuthorNames()}
|
||||||
|
Narrator(s): {libraryBook.Book.NarratorNames()}
|
||||||
|
Length: {(libraryBook.Book.LengthInMinutes == 0 ? "" : $"{libraryBook.Book.LengthInMinutes / 60} hr {libraryBook.Book.LengthInMinutes % 60} min")}
|
||||||
|
Audio Bitrate: {libraryBook.Book.AudioFormat}
|
||||||
|
Category: {string.Join(" > ", libraryBook.Book.CategoriesNames())}
|
||||||
|
Purchase Date: {libraryBook.DateAdded.ToString("d")}
|
||||||
|
Audible ID: {libraryBook.Book.AudibleProductId}
|
||||||
|
".Trim();
|
||||||
|
|
||||||
|
var seriesNames = libraryBook.Book.SeriesNames();
|
||||||
|
if (!string.IsNullOrWhiteSpace(seriesNames))
|
||||||
|
DetailsText += $"\r\nSeries: {seriesNames}";
|
||||||
|
|
||||||
|
var bookRating = libraryBook.Book.Rating?.ToStarString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(bookRating))
|
||||||
|
DetailsText += $"\r\nBook Rating:\r\n{bookRating}";
|
||||||
|
|
||||||
|
var myRating = libraryBook.Book.UserDefinedItem.Rating?.ToStarString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(myRating))
|
||||||
|
DetailsText += $"\r\nMy Rating:\r\n{myRating}";
|
||||||
|
|
||||||
|
|
||||||
|
//init book status
|
||||||
|
{
|
||||||
|
var status = libraryBook.Book.UserDefinedItem.BookStatus;
|
||||||
|
|
||||||
|
BookLiberatedItems.Add(new() { Status = LiberatedStatus.Liberated, Text = "Downloaded" });
|
||||||
|
BookLiberatedItems.Add(new() { Status = LiberatedStatus.NotLiberated, Text = "Not Downloaded" });
|
||||||
|
|
||||||
|
if (status == LiberatedStatus.Error)
|
||||||
|
BookLiberatedItems.Add(new() { Status = LiberatedStatus.Error, Text = "Error" });
|
||||||
|
|
||||||
|
BookLiberatedSelectedItem = BookLiberatedItems.SingleOrDefault(s => s.Status == status);
|
||||||
|
}
|
||||||
|
|
||||||
|
//init pdf status
|
||||||
|
{
|
||||||
|
var status = libraryBook.Book.UserDefinedItem.PdfStatus;
|
||||||
|
|
||||||
|
if (status is not null)
|
||||||
|
{
|
||||||
|
PdfLiberatedItems.Add(new() { Status = LiberatedStatus.Liberated, Text = "Downloaded" });
|
||||||
|
PdfLiberatedItems.Add(new() { Status = LiberatedStatus.NotLiberated, Text = "Not Downloaded" });
|
||||||
|
|
||||||
|
PdfLiberatedSelectedItem = PdfLiberatedItems.SingleOrDefault(s => s.Status == status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -93,7 +93,8 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
this,
|
this,
|
||||||
visibleLibraryBooks,
|
visibleLibraryBooks,
|
||||||
"Are you sure you want to remove {0} from Libation's library?",
|
"Are you sure you want to remove {0} from Libation's library?",
|
||||||
"Remove books from Libation?");
|
"Remove books from Libation?",
|
||||||
|
MessageBoxDefaultButton.Button2);
|
||||||
|
|
||||||
if (confirmationResult != DialogResult.Yes)
|
if (confirmationResult != DialogResult.Yes)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -9,6 +9,7 @@ using LibationFileManager;
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using LibationWinForms.AvaloniaUI.Views.Dialogs;
|
||||||
|
|
||||||
namespace LibationWinForms.AvaloniaUI.Views
|
namespace LibationWinForms.AvaloniaUI.Views
|
||||||
{
|
{
|
||||||
@ -55,6 +56,12 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
LibraryCommands.LibrarySizeChanged += async (_, _) => await _viewModel.ProductsDisplay.DisplayBooks(DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
|
LibraryCommands.LibrarySizeChanged += async (_, _) => await _viewModel.ProductsDisplay.DisplayBooks(DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
|
||||||
Closing += (_,_) => this.SaveSizeAndLocation(Configuration.Instance);
|
Closing += (_,_) => this.SaveSizeAndLocation(Configuration.Instance);
|
||||||
}
|
}
|
||||||
|
Opened += MainWindow_Opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void MainWindow_Opened(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProductsDisplay_Initialized1(object sender, EventArgs e)
|
public void ProductsDisplay_Initialized1(object sender, EventArgs e)
|
||||||
|
|||||||
@ -3,6 +3,8 @@ using System;
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using LibationWinForms.AvaloniaUI.ViewModels;
|
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||||
|
using ApplicationServices;
|
||||||
|
using DataLayer;
|
||||||
|
|
||||||
namespace LibationWinForms.AvaloniaUI.Views
|
namespace LibationWinForms.AvaloniaUI.Views
|
||||||
{
|
{
|
||||||
@ -15,6 +17,16 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
public ProcessBookControl2()
|
public ProcessBookControl2()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
if (Design.IsDesignMode)
|
||||||
|
{
|
||||||
|
using var context = DbContexts.GetContext();
|
||||||
|
DataContext = new ProcessBook2(
|
||||||
|
context.GetLibraryBook_Flat_NoTracking("B017V4IM1G"),
|
||||||
|
ProcessQueue.LogMe.RegisterForm(default(ProcessQueue.ILogForm))
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProcessBook2 DataItem => DataContext is null ? null : DataContext as ProcessBook2;
|
private ProcessBook2 DataItem => DataContext is null ? null : DataContext as ProcessBook2;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ using ApplicationServices;
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using DataLayer;
|
||||||
using LibationWinForms.AvaloniaUI.ViewModels;
|
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -19,7 +20,70 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
ProcessBookControl2.PositionButtonClicked += ProcessBookControl2_ButtonClicked;
|
ProcessBookControl2.PositionButtonClicked += ProcessBookControl2_ButtonClicked;
|
||||||
ProcessBookControl2.CancelButtonClicked += ProcessBookControl2_CancelButtonClicked;
|
ProcessBookControl2.CancelButtonClicked += ProcessBookControl2_CancelButtonClicked;
|
||||||
|
|
||||||
|
#region Design Mode Testing
|
||||||
|
if (Design.IsDesignMode)
|
||||||
|
{
|
||||||
|
var vm = new ProcessQueueViewModel();
|
||||||
|
var Logger = ProcessQueue.LogMe.RegisterForm(vm);
|
||||||
|
DataContext = vm;
|
||||||
|
using var context = DbContexts.GetContext();
|
||||||
|
List<ProcessBook2> testList = new()
|
||||||
|
{
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4IM1G"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.FailedAbort,
|
||||||
|
Status = ProcessBookStatus.Failed,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4IWVG"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.FailedSkip,
|
||||||
|
Status = ProcessBookStatus.Failed,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4JA2Q"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.FailedRetry,
|
||||||
|
Status = ProcessBookStatus.Failed,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4NUPO"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.ValidationFail,
|
||||||
|
Status = ProcessBookStatus.Failed,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4NMX4"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.Cancelled,
|
||||||
|
Status = ProcessBookStatus.Cancelled,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4NOZ0"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.Success,
|
||||||
|
Status = ProcessBookStatus.Completed,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017WJ5ZK6"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.None,
|
||||||
|
Status = ProcessBookStatus.Working,
|
||||||
|
},
|
||||||
|
new ProcessBook2(context.GetLibraryBook_Flat_NoTracking("B017V4IM1G"), Logger)
|
||||||
|
{
|
||||||
|
Result = ProcessBookResult.None,
|
||||||
|
Status = ProcessBookStatus.Queued,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.Items.Enqueue(testList);
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
vm.Items.MoveNext();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using ApplicationServices;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
@ -5,6 +6,7 @@ using DataLayer;
|
|||||||
using FileLiberator;
|
using FileLiberator;
|
||||||
using LibationFileManager;
|
using LibationFileManager;
|
||||||
using LibationWinForms.AvaloniaUI.ViewModels;
|
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||||
|
using LibationWinForms.AvaloniaUI.Views.Dialogs;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -21,8 +23,25 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
public ProductsDisplay2()
|
public ProductsDisplay2()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Configure_ColumnCustomization();
|
|
||||||
|
|
||||||
|
if (Design.IsDesignMode)
|
||||||
|
{
|
||||||
|
using var context = DbContexts.GetContext();
|
||||||
|
List<GridEntry2> sampleEntries = new()
|
||||||
|
{
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017V4IM1G")),
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017V4IWVG")),
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017V4JA2Q")),
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017V4NUPO")),
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017V4NMX4")),
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017V4NOZ0")),
|
||||||
|
new LibraryBookEntry2(context.GetLibraryBook_Flat_NoTracking("B017WJ5ZK6")),
|
||||||
|
};
|
||||||
|
DataContext = new ProductsDisplayViewModel(sampleEntries);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Configure_ColumnCustomization();
|
||||||
foreach (var column in productsGrid.Columns)
|
foreach (var column in productsGrid.Columns)
|
||||||
{
|
{
|
||||||
column.CustomSortComparer = new RowComparer(column);
|
column.CustomSortComparer = new RowComparer(column);
|
||||||
@ -251,15 +270,23 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BookDetailsDialog2 bookDetailsForm;
|
||||||
|
|
||||||
public void OnTagsButtonClick(object sender, Avalonia.Interactivity.RoutedEventArgs args)
|
public void OnTagsButtonClick(object sender, Avalonia.Interactivity.RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
var button = args.Source as Button;
|
var button = args.Source as Button;
|
||||||
|
|
||||||
if (button.DataContext is LibraryBookEntry2 lbEntry)
|
if (button.DataContext is LibraryBookEntry2 lbEntry && VisualRoot is Window window)
|
||||||
{
|
{
|
||||||
var bookDetailsForm = new LibationWinForms.Dialogs.BookDetailsDialog(lbEntry.LibraryBook);
|
if (bookDetailsForm is null || !bookDetailsForm.IsVisible)
|
||||||
if (bookDetailsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
{
|
||||||
lbEntry.Commit(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
|
bookDetailsForm = new BookDetailsDialog2(lbEntry.LibraryBook);
|
||||||
|
bookDetailsForm.RestoreSizeAndLocation(Configuration.Instance);
|
||||||
|
bookDetailsForm.Closing += (_,_) => bookDetailsForm.SaveSizeAndLocation(Configuration.Instance);
|
||||||
|
bookDetailsForm.Show(window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bookDetailsForm.LibraryBook = lbEntry.LibraryBook;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -109,6 +109,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Update="AvaloniaUI\Views\Dialogs\BookDetailsDialog2.axaml.cs">
|
||||||
|
<DependentUpon>BookDetailsDialog2.axaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Update="Properties\Resources.Designer.cs">
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@ -123,4 +126,8 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<UpToDateCheckInput Remove="AvaloniaUI\Controls\GroupBox.axaml" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@ -29,7 +29,7 @@ namespace LibationWinForms
|
|||||||
/*
|
/*
|
||||||
Results below compare startup times when parallelizing startup tasks vs when
|
Results below compare startup times when parallelizing startup tasks vs when
|
||||||
running everything sequentially, from the entry point until after the call to
|
running everything sequentially, from the entry point until after the call to
|
||||||
OnLoadedLibrary() returns. Tests were run on a ReadyToRun enables release build.
|
OnLoadedLibrary() returns. Tests were run on a ReadyToRun enabled release build.
|
||||||
|
|
||||||
The first run is substantially slower than all subsequent runs for both serial
|
The first run is substantially slower than all subsequent runs for both serial
|
||||||
and parallel. This is most likely due to file system caching speeding up
|
and parallel. This is most likely due to file system caching speeding up
|
||||||
@ -54,7 +54,7 @@ namespace LibationWinForms
|
|||||||
Min 1492 2316
|
Min 1492 2316
|
||||||
Q1 1562 2358
|
Q1 1562 2358
|
||||||
Med 1567 2379
|
Med 1567 2379
|
||||||
Q2 1600 2418
|
Q3 1600 2418
|
||||||
Max 2837 5835
|
Max 2837 5835
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
//For debug purposes, always run AvaloniaUI.
|
//For debug purposes, always run AvaloniaUI.
|
||||||
if (true) //(config.GetNonString<bool>("BetaOptIn"))
|
if (config.GetNonString<bool>("BetaOptIn"))
|
||||||
{
|
{
|
||||||
//Start as much work in parallel as possible.
|
//Start as much work in parallel as possible.
|
||||||
var runDbMigrationsTask = Task.Run(() => RunDbMigrations(config));
|
var runDbMigrationsTask = Task.Run(() => RunDbMigrations(config));
|
||||||
|
|||||||
@ -5,13 +5,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>x64</Platform>
|
<Platform>Any CPU</Platform>
|
||||||
<PublishDir>..\bin\publish\</PublishDir>
|
<PublishDir>..\bin\publish\</PublishDir>
|
||||||
<PublishProtocol>FileSystem</PublishProtocol>
|
<PublishProtocol>FileSystem</PublishProtocol>
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<SelfContained>false</SelfContained>
|
<SelfContained>false</SelfContained>
|
||||||
<PublishSingleFile>false</PublishSingleFile>
|
<PublishSingleFile>false</PublishSingleFile>
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
x
Reference in New Issue
Block a user