Added book details dialog

This commit is contained in:
Michael Bucari-Tovo 2022-07-16 15:06:37 -06:00
parent 35f677a0fa
commit 952173d450
16 changed files with 516 additions and 88 deletions

View 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>

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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&#xA;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>

View File

@ -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);
}
}
}
}
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;
@ -20,6 +21,69 @@ namespace LibationWinForms.AvaloniaUI.Views
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()

View File

@ -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;
} }
} }

View File

@ -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>

View File

@ -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));

View File

@ -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>