Initial
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
16
Bokhantarare.sln
Normal file
16
Bokhantarare.sln
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bokhantarare", "Bokhantarare\Bokhantarare.csproj", "{3FCD531B-F2FB-462E-981D-3150093064E3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3FCD531B-F2FB-462E-981D-3150093064E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3FCD531B-F2FB-462E-981D-3150093064E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3FCD531B-F2FB-462E-981D-3150093064E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3FCD531B-F2FB-462E-981D-3150093064E3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
9
Bokhantarare/App.xaml
Normal file
9
Bokhantarare/App.xaml
Normal file
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="Bokhantarare.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Bokhantarare"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
13
Bokhantarare/App.xaml.cs
Normal file
13
Bokhantarare/App.xaml.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace Bokhantarare;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
|
||||
10
Bokhantarare/AssemblyInfo.cs
Normal file
10
Bokhantarare/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly:ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
50
Bokhantarare/BareBookInfo.cs
Normal file
50
Bokhantarare/BareBookInfo.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
|
||||
namespace Bokhantarare;
|
||||
|
||||
public class BareBookInfo(string editionId, string title, string? workId = null)
|
||||
{
|
||||
string WorkID { get; set; } = workId??"";
|
||||
string EditionID { get; set; } = editionId;
|
||||
string Title { get; set; } = title;
|
||||
|
||||
public Book getBook()
|
||||
{
|
||||
Dictionary<String, Object>? responce = JsonSerializer.Deserialize<Dictionary<String, Object>>(
|
||||
Helper.Request($"https://openlibrary.org/books/{EditionID}.json"));
|
||||
|
||||
if (responce == null)
|
||||
{
|
||||
throw new Exception("Failed to get book info");
|
||||
}
|
||||
|
||||
object? isbn_13_raw_array = 0;
|
||||
if (responce.ContainsKey("isbn_13"))
|
||||
{
|
||||
isbn_13_raw_array = responce["isbn_13"];
|
||||
}
|
||||
else if(responce.ContainsKey("isbn_10"))
|
||||
{
|
||||
isbn_13_raw_array = responce["isbn_10"];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Failed to get ISBN");
|
||||
}
|
||||
if (isbn_13_raw_array == null)
|
||||
{
|
||||
throw new Exception("Failed to get book info");
|
||||
}
|
||||
|
||||
List<string> isbn_13_array = JsonSerializer.Deserialize<List<string>>(isbn_13_raw_array.ToString());
|
||||
|
||||
return Book.GetBookFromISBN(isbn_13_array[0])??throw new Exception("Failed to get book info");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
}
|
||||
11
Bokhantarare/Bokhantarare.csproj
Normal file
11
Bokhantarare/Bokhantarare.csproj
Normal file
@@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
129
Bokhantarare/Book.cs
Normal file
129
Bokhantarare/Book.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Bokhantarare;
|
||||
|
||||
public class Book
|
||||
{
|
||||
[JsonPropertyName("ISBN")]
|
||||
public string ISBN { get; set; }
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
[JsonPropertyName("authors")]
|
||||
public string[] Authors { get; set; }
|
||||
[JsonPropertyName("publicationYear")]
|
||||
public string PubYear { get; set; }
|
||||
|
||||
public Book()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Book(string ISBN, string title, string[] authors, string pubYear)
|
||||
{
|
||||
this.ISBN = ISBN;
|
||||
this.Title = title;
|
||||
this.Authors = authors;
|
||||
this.PubYear = pubYear;
|
||||
}
|
||||
|
||||
public Book(string ISBN, string title, string author, string pubYear) : this(ISBN, title, [author], pubYear)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Title: {Title}, Authors: {string.Join(", ", Authors)}, PubDate: {PubYear}";
|
||||
}
|
||||
|
||||
public static Book? GetBookFromISBN(string ISBN)
|
||||
{
|
||||
ISBN = ISBN.Replace("-", "").Trim();
|
||||
if (ISBN.Length != 10 && ISBN.Length != 13)
|
||||
{
|
||||
throw new ArgumentException("Invalid ISBN");
|
||||
}
|
||||
|
||||
Dictionary<String, Object>? responce = JsonSerializer.Deserialize<Dictionary<String, Object>>(
|
||||
Helper.Request($"https://openlibrary.org/api/books?bibkeys=ISBN:{ISBN}&jscmd=details&format=json"));
|
||||
|
||||
if (responce == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Dictionary<String, Object>? book = JsonSerializer.Deserialize<Dictionary<String, Object>>(responce[$"ISBN:{ISBN}"].ToString());
|
||||
Dictionary<String, Object>? details = JsonSerializer.Deserialize<Dictionary<String, Object>>(book["details"].ToString());
|
||||
|
||||
string title = "";
|
||||
if (details.ContainsKey("full_title"))
|
||||
{
|
||||
title = details["full_title"].ToString();
|
||||
}
|
||||
else if (details.ContainsKey("title"))
|
||||
{
|
||||
title = details["title"].ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
title = "Missing title";
|
||||
}
|
||||
List<string> authors = new List<string>();
|
||||
if (details.ContainsKey("authors"))
|
||||
{
|
||||
foreach (Dictionary<string, object> listAuthors in JsonSerializer.Deserialize<Dictionary<String, Object>[]>(
|
||||
details["authors"].ToString()))
|
||||
{
|
||||
authors.Add(listAuthors["name"].ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
authors.Add("Missing Authors");
|
||||
}
|
||||
|
||||
string pubDate = "";
|
||||
if (details.ContainsKey("publish_date"))
|
||||
{
|
||||
details["publish_date"].ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
pubDate = "No Publication Date";
|
||||
}
|
||||
return new Book(ISBN, title, authors.ToArray(), pubDate);
|
||||
}
|
||||
|
||||
public static BareBookInfo[]? GetBooksFromTitle(string title)
|
||||
{
|
||||
title = title.Trim();
|
||||
|
||||
Dictionary<String, Object>? responce = JsonSerializer.Deserialize<Dictionary<String, Object>>(
|
||||
Helper.Request($"https://openlibrary.org/search.json?q={title}"));
|
||||
|
||||
if (responce == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Dictionary<String, Object>>? books = JsonSerializer.Deserialize<List<Dictionary<String, Object>>>(responce["docs"].ToString());
|
||||
|
||||
List<BareBookInfo> bookInfos = new List<BareBookInfo>();
|
||||
|
||||
foreach (Dictionary<String, Object> book in books)
|
||||
{
|
||||
if (book.TryGetValue("cover_edition_key", out var edition) && book.TryGetValue("title", out var value))
|
||||
{
|
||||
bookInfos.Add(new BareBookInfo(edition.ToString(), value.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a debug line to list search results that where missing the cover_edition_key
|
||||
//Console.WriteLine(JsonSerializer.Serialize(book));
|
||||
}
|
||||
}
|
||||
|
||||
return bookInfos.ToArray();
|
||||
}
|
||||
}
|
||||
19
Bokhantarare/BookSelectionPage.xaml
Normal file
19
Bokhantarare/BookSelectionPage.xaml
Normal file
@@ -0,0 +1,19 @@
|
||||
<Window x:Class="Bokhantarare.BookSelectionPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Bokhantarare"
|
||||
mc:Ignorable="d"
|
||||
Title="BookSelectionPage" Height="90" Width="180">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="Select the book you wish to add" Margin="0,0,0,5"/>
|
||||
<ComboBox Grid.Row="1" Name="BookSelector"></ComboBox>
|
||||
<Button Grid.Row="2" Content="Ok" Click="ButtonBase_OnClick"></Button>
|
||||
</Grid>
|
||||
</Window>
|
||||
27
Bokhantarare/BookSelectionPage.xaml.cs
Normal file
27
Bokhantarare/BookSelectionPage.xaml.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace Bokhantarare;
|
||||
|
||||
public partial class BookSelectionPage : Window
|
||||
{
|
||||
public BookSelectionPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public BookSelectionPage(BareBookInfo[] books) : this()
|
||||
{
|
||||
BookSelector.ItemsSource = books;
|
||||
}
|
||||
|
||||
public BareBookInfo getSelectedBook()
|
||||
{
|
||||
return BookSelector.SelectedItem as BareBookInfo;
|
||||
}
|
||||
|
||||
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.DialogResult = true; // Close the dialog with 'OK' result.
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
21
Bokhantarare/Helper.cs
Normal file
21
Bokhantarare/Helper.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace Bokhantarare;
|
||||
|
||||
public class Helper
|
||||
{
|
||||
public static string Request(string requestUrl)
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl);
|
||||
requestMessage.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
||||
|
||||
//Connect to the URL
|
||||
HttpResponseMessage response = client.SendAsync(requestMessage).Result;
|
||||
|
||||
// Get the response
|
||||
string Output = response.Content.ReadAsStringAsync().Result;
|
||||
return Output;
|
||||
}
|
||||
}
|
||||
113
Bokhantarare/MainWindow.xaml
Normal file
113
Bokhantarare/MainWindow.xaml
Normal file
@@ -0,0 +1,113 @@
|
||||
<Window x:Class="Bokhantarare.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:local="clr-namespace:Bokhantarare"
|
||||
mc:Ignorable="d"
|
||||
Title="MainWindow" Height="450" Width="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="10"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox Grid.Row="0" Grid.Column="0" Text="" TextChanged="ISBN_OnTextChange" x:Name="ISBN" Width="110"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" x:Name="ISBNPlaceholderText"
|
||||
Text="Enter ISBN here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
<Button Grid.Row="1" Grid.Column="0" Content="Search by ISBN" ToolTip="This searches for a book(s) on openlibrary" Click="SearchByISBN"/>
|
||||
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="" TextChanged="Title_OnTextChange" x:Name="Title" Width="110"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" x:Name="TitlePlaceholderText"
|
||||
Text="Enter Title here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Content="Search by Title" ToolTip="This searches for a book(s) on openlibrary" Click="SearchByTitle"/>
|
||||
|
||||
<TextBox Grid.Row="0" Grid.Column="3" Text="" TextChanged="CustomTitle_OnTextChange" x:Name="CustomTitle" Width="110"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="3" x:Name="CustomTitlePlaceholderText"
|
||||
Text="Enter Title here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
|
||||
<TextBox Grid.Row="0" Grid.Column="4" Text="" TextChanged="CustomISBN_OnTextChange" x:Name="CustomISBN" Width="110"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="4" x:Name="CustomISBNPlaceholderText"
|
||||
Text="Enter ISBN here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
|
||||
<TextBox Grid.Row="0" Grid.Column="5" Text="" TextChanged="CustomAuthor_OnTextChange" x:Name="CustomAuthor" Width="110" ToolTip="This is a comma separated field to allow multiple entries"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="5" x:Name="CustomAuthorPlaceholderText"
|
||||
Text="Enter Author here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
|
||||
<TextBox Grid.Row="0" Grid.Column="6" Text="" TextChanged="CustomPubYear_OnTextChange" x:Name="CustomPubYear" Width="145"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="6" x:Name="CustomPubYearPlaceholderText"
|
||||
Text="Enter Publishing Year here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="3" Content="Create Entry" ToolTip="This Adds a book with the given properties" Click="CustomEntry"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0" x:Name="Books">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox Grid.Row="0" Text="" TextChanged="Search_OnTextChange" x:Name="Search" ToolTip="Search by name"/>
|
||||
<TextBlock Grid.Row="0" x:Name="SearchPlaceholderText"
|
||||
Text="Enter Title to search for here..."
|
||||
VerticalAlignment="Top"
|
||||
Foreground="Gray"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Visible" />
|
||||
<Grid Grid.Row="1" Name="Library" MouseWheel="ScrolLibrary">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ScrollBar Grid.Column="1" Orientation="Vertical" Minimum="1" Maximum="1" Scroll="ScrollView" x:Name="ScrollBar"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
395
Bokhantarare/MainWindow.xaml.cs
Normal file
395
Bokhantarare/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
using System.IO;
|
||||
using System.Net.Cache;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Bokhantarare;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private List<Book> books = new();
|
||||
private List<Book> booksFiltered = new();
|
||||
public MainWindow()
|
||||
{
|
||||
if (File.Exists("./books.json"))
|
||||
{
|
||||
books = JsonSerializer.Deserialize<List<Book>>(File.ReadAllText("./books.json"));
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
ScrollBar.Minimum = 0;
|
||||
ScrollBar.Maximum = books.Count-6;
|
||||
|
||||
if (ScrollBar.Maximum <= 0)
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
uppdateListedBooks(0);
|
||||
|
||||
Console.WriteLine(Book.GetBookFromISBN("978-1-97470719-5"));
|
||||
|
||||
AppDomain.CurrentDomain.ProcessExit += (_, __) =>
|
||||
{
|
||||
File.WriteAllText("books.json", JsonSerializer.Serialize(books));
|
||||
};
|
||||
}
|
||||
|
||||
public void uppdateListedBooks(int offset, List<Book> listedBooks = null)
|
||||
{
|
||||
if (listedBooks == null || listedBooks.Count == 0)
|
||||
{
|
||||
listedBooks = books;
|
||||
}
|
||||
|
||||
if (offset > listedBooks.Count)
|
||||
{
|
||||
offset = 0;
|
||||
ScrollBar.Value = 0;
|
||||
}
|
||||
|
||||
List<Book> shown = listedBooks.GetRange(offset, Math.Min(6, listedBooks.Count - offset));
|
||||
|
||||
int i = 0;
|
||||
|
||||
Library.Children.Clear();
|
||||
|
||||
foreach (Book book in shown)
|
||||
{
|
||||
|
||||
Grid grid = new Grid();
|
||||
|
||||
grid.Margin = new Thickness(0, 5, 0, 0);
|
||||
grid.SetValue(Grid.RowProperty, i);
|
||||
i++;
|
||||
|
||||
ColumnDefinition def1 = new ColumnDefinition();
|
||||
def1.Width = new GridLength(40);
|
||||
grid.ColumnDefinitions.Add(def1);
|
||||
|
||||
ColumnDefinition def2 = new ColumnDefinition();
|
||||
def2.Width = GridLength.Auto;
|
||||
grid.ColumnDefinitions.Add(def2);
|
||||
|
||||
ColumnDefinition def7 = new ColumnDefinition();
|
||||
def2.Width = GridLength.Auto;
|
||||
grid.ColumnDefinitions.Add(def7);
|
||||
|
||||
BitmapImage coverBitmap = new BitmapImage();
|
||||
coverBitmap.BeginInit();
|
||||
coverBitmap.UriSource = new Uri($"https://covers.openlibrary.org/b/isbn/{book.ISBN}-S.jpg");
|
||||
coverBitmap.CacheOption = BitmapCacheOption.OnLoad; // Ensure full load before use
|
||||
//coverBitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache; // Prevent caching issues
|
||||
coverBitmap.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.Default); // Network-friendly caching
|
||||
coverBitmap.EndInit();
|
||||
|
||||
Image cover = new Image();
|
||||
cover.SetValue(Grid.ColumnProperty, 0);
|
||||
cover.Stretch = Stretch.Uniform;
|
||||
cover.Source = coverBitmap;
|
||||
cover.Margin = new Thickness(0, 0, 5, 0);
|
||||
|
||||
grid.Children.Add(cover);
|
||||
|
||||
Grid bookInfo = new Grid();
|
||||
|
||||
bookInfo.SetValue(Grid.ColumnProperty, 1);
|
||||
|
||||
RowDefinition def3 = new RowDefinition();
|
||||
def3.Height = GridLength.Auto;
|
||||
bookInfo.RowDefinitions.Add(def3);
|
||||
|
||||
RowDefinition def4 = new RowDefinition();
|
||||
bookInfo.RowDefinitions.Add(def4);
|
||||
|
||||
TextBlock title = new TextBlock();
|
||||
title.Text = book.Title;
|
||||
title.SetValue(Grid.RowProperty, 0);
|
||||
bookInfo.Children.Add(title);
|
||||
|
||||
Grid spesificInfo = new Grid();
|
||||
spesificInfo.SetValue(Grid.RowProperty, 1);
|
||||
|
||||
spesificInfo.RowDefinitions.Add(new RowDefinition());
|
||||
spesificInfo.RowDefinitions.Add(new RowDefinition());
|
||||
|
||||
TextBlock author = new TextBlock();
|
||||
author.Text = $"Author{(book.Authors.Length == 1 ? "" : "s")} {(book.Authors.Length == 1 ? book.Authors[0] : string.Join(", ", book.Authors))}";
|
||||
author.SetValue(Grid.RowProperty, 0);
|
||||
spesificInfo.Children.Add(author);
|
||||
|
||||
TextBlock year = new TextBlock();
|
||||
year.Text = $"Year {(book.PubYear)}";
|
||||
year.SetValue(Grid.RowProperty, 1);
|
||||
spesificInfo.Children.Add(year);
|
||||
|
||||
bookInfo.Children.Add(spesificInfo);
|
||||
|
||||
grid.Children.Add(bookInfo);
|
||||
|
||||
BitmapImage removeBitmap = new BitmapImage();
|
||||
removeBitmap.BeginInit();
|
||||
removeBitmap.UriSource = new Uri($"{Environment.CurrentDirectory}/recycle-bin.png");
|
||||
removeBitmap.CacheOption = BitmapCacheOption.OnLoad; // Ensure full load before use
|
||||
//removeBitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache; // Prevent caching issues
|
||||
removeBitmap.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.Default); // Network-friendly caching
|
||||
removeBitmap.EndInit();
|
||||
|
||||
Image removeImage = new Image();
|
||||
removeImage.SetValue(Grid.ColumnProperty, 0);
|
||||
removeImage.Stretch = Stretch.Uniform;
|
||||
removeImage.Source = removeBitmap;
|
||||
removeImage.MaxHeight = 20;
|
||||
removeImage.MaxWidth = 20;
|
||||
removeImage.Margin = new Thickness(0, 0, 5, 0);
|
||||
|
||||
Button remove = new Button();
|
||||
remove.Click += (_, __) => RemoveBook(book);
|
||||
remove.Content = removeImage;
|
||||
remove.MaxWidth = 30;
|
||||
remove.SetValue(Grid.ColumnProperty, 2);
|
||||
|
||||
grid.Children.Add(remove);
|
||||
|
||||
Library.Children.Add(grid);
|
||||
}
|
||||
|
||||
Library.UpdateLayout();
|
||||
}
|
||||
|
||||
private void ISBN_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
ISBNPlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
private void Title_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
TitlePlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void CustomTitle_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
CustomTitlePlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void CustomISBN_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
CustomISBNPlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void CustomAuthor_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
CustomAuthorPlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void CustomPubYear_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
CustomPubYearPlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void CustomEntry(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Book book = new Book(CustomISBN.Text, CustomTitle.Text, CustomAuthor.Text.Split(", "), CustomPubYear.Text);
|
||||
string messageBoxText = $"Are you sure you want to save the book?\nTitle: {book.Title}\nAuthors: {string.Join(", ", book.Authors)}\nPublising year: {book.PubYear}";
|
||||
string caption = "Add Entry";
|
||||
MessageBoxButton button = MessageBoxButton.YesNo;
|
||||
MessageBoxImage icon = MessageBoxImage.Question;
|
||||
MessageBoxResult result;
|
||||
|
||||
result = MessageBox.Show(messageBoxText, caption, button, icon, MessageBoxResult.Yes);
|
||||
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
if (books.Any(b => b.Title == book.Title))
|
||||
{
|
||||
MessageBox.Show("Book already in Library", "Found book", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBook(book);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchByISBN(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Book book;
|
||||
try
|
||||
{
|
||||
book = Book.GetBookFromISBN(ISBN.Text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show($"Found: {book.Title}", "Found book", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
if (books.Any(b => b.Title == book.Title))
|
||||
{
|
||||
MessageBox.Show("Book already in Library", "Found book", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBook(book);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddBook(Book book)
|
||||
{
|
||||
books.Add(book);
|
||||
ScrollBar.Maximum = books.Count-6;
|
||||
uppdateListedBooks((int)Math.Floor(ScrollBar.Value*books.Count), booksFiltered);
|
||||
if (ScrollBar.Maximum > 6)
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveBook(Book book)
|
||||
{
|
||||
books.Remove(book);
|
||||
ScrollBar.Maximum = books.Count-6;
|
||||
uppdateListedBooks((int)Math.Floor(ScrollBar.Value*books.Count));
|
||||
if (ScrollBar.Maximum == 0)
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchByTitle(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
BareBookInfo[]? books = Book.GetBooksFromTitle(Title.Text);
|
||||
|
||||
if (books == null)
|
||||
{
|
||||
MessageBox.Show("No books found", "No books", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Found {books.Length} with the title \"{Title.Text}\"");
|
||||
|
||||
BookSelectionPage selectionPage = new BookSelectionPage(books);
|
||||
selectionPage.ShowDialog();
|
||||
|
||||
if (selectionPage.DialogResult.HasValue && selectionPage.DialogResult.Value)
|
||||
{
|
||||
BareBookInfo selectedBook = selectionPage.getSelectedBook();
|
||||
AddBook(selectedBook.getBook());
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("No books found", "No books", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollView(object sender, ScrollEventArgs e)
|
||||
{
|
||||
if (sender is ScrollBar scrollBar)
|
||||
{
|
||||
uppdateListedBooks((int)Math.Floor(scrollBar.Value*books.Count), booksFiltered);
|
||||
}
|
||||
}
|
||||
|
||||
private void Search_OnTextChange(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
SearchPlaceholderText.Visibility = string.IsNullOrEmpty(textBox.Text)
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
|
||||
if (string.IsNullOrEmpty(textBox.Text))
|
||||
{
|
||||
ScrollBar.Maximum = books.Count - 6;
|
||||
if (ScrollBar.Maximum <= 0)
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Visible;
|
||||
}
|
||||
ScrollBar.Value = 0;
|
||||
booksFiltered = null;
|
||||
uppdateListedBooks((int)Math.Floor(ScrollBar.Value*books.Count), booksFiltered);
|
||||
}
|
||||
else
|
||||
{
|
||||
booksFiltered = books.Where(b => b.Title.ToLower().Contains(textBox.Text.ToLower())).ToList();
|
||||
ScrollBar.Maximum = booksFiltered.Count - 6;
|
||||
if (ScrollBar.Maximum <= 0)
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScrollBar.Visibility = Visibility.Visible;
|
||||
}
|
||||
ScrollBar.Value = 0;
|
||||
uppdateListedBooks((int)Math.Floor(ScrollBar.Value*books.Count), booksFiltered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrolLibrary(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
int value = (int)Math.Floor(ScrollBar.Value + e.Delta / 120);
|
||||
|
||||
ScrollBar.Value = Math.Min(ScrollBar.Maximum, value);
|
||||
uppdateListedBooks((int)Math.Floor(ScrollBar.Value*books.Count), booksFiltered);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user