From 8249d9a27b2b5171af9e4887a711b1c03ae9abab Mon Sep 17 00:00:00 2001 From: lvas463 Date: Tue, 17 Oct 2023 14:25:14 -0400 Subject: [PATCH] Added .gitignore and created delete window. --- .gitignore | 1 + PcgsInvUi/App.axaml | 2 +- PcgsInvUi/App.axaml.cs | 1 + PcgsInvUi/Models/Coin.cs | 65 +++++++++++++---- PcgsInvUi/Services/PcgsClient.cs | 37 ++++++++-- PcgsInvUi/ViewModels/DeleteWindowViewModel.cs | 14 ++++ PcgsInvUi/ViewModels/EditViewModel.cs | 4 +- PcgsInvUi/ViewModels/MainWindowViewModel.cs | 70 +++++++------------ PcgsInvUi/ViewModels/NewViewModel.cs | 36 ++++++---- PcgsInvUi/Views/DeleteWindow.axaml | 8 +-- PcgsInvUi/Views/DeleteWindow.axaml.cs | 25 ++----- PcgsInvUi/Views/MainWindow.axaml | 32 ++++----- PcgsInvUi/Views/MainWindow.axaml.cs | 18 +++-- PcgsInvUi/Views/NewView.axaml | 2 +- 14 files changed, 188 insertions(+), 127 deletions(-) create mode 100644 .gitignore create mode 100644 PcgsInvUi/ViewModels/DeleteWindowViewModel.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df3fb97 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/PcgsInvUi/bin/ diff --git a/PcgsInvUi/App.axaml b/PcgsInvUi/App.axaml index a175947..14b1cc2 100644 --- a/PcgsInvUi/App.axaml +++ b/PcgsInvUi/App.axaml @@ -2,7 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="PcgsInvUi.App" xmlns:local="using:PcgsInvUi" - RequestedThemeVariant="Dark"> + RequestedThemeVariant="Light"> diff --git a/PcgsInvUi/App.axaml.cs b/PcgsInvUi/App.axaml.cs index 42647b1..b4c71cb 100644 --- a/PcgsInvUi/App.axaml.cs +++ b/PcgsInvUi/App.axaml.cs @@ -1,6 +1,7 @@ using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using PcgsInvUi.Services; using PcgsInvUi.ViewModels; using PcgsInvUi.Views; diff --git a/PcgsInvUi/Models/Coin.cs b/PcgsInvUi/Models/Coin.cs index fb045a9..a275fcd 100644 --- a/PcgsInvUi/Models/Coin.cs +++ b/PcgsInvUi/Models/Coin.cs @@ -5,12 +5,12 @@ namespace PcgsInvUi.Models; public class Coin : ReactiveObject { - public int PcgsNumber + public string PCGSNo { - get => _pcgsNumber; - set => this.RaiseAndSetIfChanged(ref _pcgsNumber, value); + get => _pcgsNo; + set => this.RaiseAndSetIfChanged(ref _pcgsNo, value); } - private int _pcgsNumber; + private string _pcgsNo; public string Name { @@ -50,8 +50,13 @@ public class Coin : ReactiveObject public double PriceGuideValue { get => _priceGuideValue; - set => this.RaiseAndSetIfChanged(ref _priceGuideValue, value); + set + { + TotalPrice = value * Quantity; + this.RaiseAndSetIfChanged(ref _priceGuideValue, value); + } } + private double _priceGuideValue; public string CoinFactsLink @@ -82,12 +87,12 @@ public class Coin : ReactiveObject } private string _dieVariety; - public string Series + public string SeriesName { - get => _series; - set => this.RaiseAndSetIfChanged(ref _series, value); + get => _seriesName; + set => this.RaiseAndSetIfChanged(ref _seriesName, value); } - private string _series; + private string _seriesName; public string Category { @@ -113,11 +118,21 @@ public class Coin : ReactiveObject public int Quantity { get => _quantity; - set => this.RaiseAndSetIfChanged(ref _quantity, value); + set + { + TotalPrice = value * PriceGuideValue; + this.RaiseAndSetIfChanged(ref _quantity, value); + } } + private int _quantity; - - public double TotalPrice => Quantity * PriceGuideValue; + + public double TotalPrice + { + get => _totalPrice; + set => this.RaiseAndSetIfChanged(ref _totalPrice, value); + } + private double _totalPrice; public double PaidFor { @@ -126,10 +141,34 @@ public class Coin : ReactiveObject } private double _paidFor; - public String Notes + public string Notes { get => _notes; set => this.RaiseAndSetIfChanged(ref _notes, value); } private string _notes; + + public Coin() + { + PCGSNo = ""; + Name = ""; + Year = 0; + Denomination = ""; + MintMark = ""; + Grade = ""; + PriceGuideValue = 0; + CoinFactsLink = ""; + MajorVariety = ""; + MinorVariety = ""; + DieVariety = ""; + SeriesName = ""; + Category = ""; + Designation = ""; + CertificateNumber = 0; + Quantity = 0; + PaidFor = 0; + Notes = ""; + + + } } \ No newline at end of file diff --git a/PcgsInvUi/Services/PcgsClient.cs b/PcgsInvUi/Services/PcgsClient.cs index b6bf2a7..aece00c 100644 --- a/PcgsInvUi/Services/PcgsClient.cs +++ b/PcgsInvUi/Services/PcgsClient.cs @@ -2,9 +2,12 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; -using Newtonsoft.Json; +// using Newtonsoft.Json; using PcgsInvUi.Models; +using System.Text.Json; +using System.Text.Json.Serialization; + namespace PcgsInvUi.Services; public class PcgsClient @@ -14,23 +17,30 @@ public class PcgsClient public PcgsClient(string apiKey) { - _apiKey = apiKey; + // _apiKey = apiKey; + _apiKey = + "E8xivTVN_k4Q8ubk8Xv_uU11U91WX0wDht4S4m4BAf2HPmKnGrZ0J2f9nccM7Ns1VkGoT1SXYR74I7aNaMKqXlJGEy3oobseKV0nGiqu1IKvFkOTVjhV37SWUVExSDFMC6FLzs7xJQIHwkcxr5JFOQNmc4ZytEh_-hmCN3NL-z0fEk98tzBmPJ_F7bq_xNru86QMD2A9yalu_dWe-lCysfyE2bCA2EDqwvWenRYf-0XnNtp6qlxxCMlCd-TDqqRKLC3qefCwpXSemwBiNSP5gbC9pwcKrZugkruuJ0nyxxThZymm"; } - public async Task GetCoinFactsByGrade(int pcgsNumber, int grade, bool plusGrade) + public async Task GetCoinFactsByGrade(int pcgsNumber, string grade, bool plusGrade = false) { Coin newCoin = null; using (HttpClient client = new HttpClient()) { + var gradeParam = GetGradeFromString(grade); + string requestUri = - $"{_apiUri}/coindetail/GetCoinFactsByGrade/?PCGSNo={pcgsNumber}&GradeNo={grade}&PlusGrade={plusGrade}"; + $"{_apiUri}/coindetail/GetCoinFactsByGrade/?PCGSNo={pcgsNumber}&GradeNo={gradeParam}&PlusGrade={plusGrade}"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", _apiKey); + Console.WriteLine($"Sending request to {requestUri}"); HttpResponseMessage response = await client.GetAsync(requestUri); + Console.WriteLine("Got response."); if (response.IsSuccessStatusCode) { string jsonResponse = await response.Content.ReadAsStringAsync(); newCoin = ParseJsonResponse(jsonResponse); + Console.WriteLine("Coin created."); } else { @@ -40,12 +50,25 @@ public class PcgsClient return newCoin; } - - // TODO Will eventually create the other methods that are included in the Public API. + private int GetGradeFromString(string grade) + { + var actualGrade = int.Parse(grade.Substring(grade.Length - 2)); + Console.WriteLine($"Grade is {actualGrade}"); + return actualGrade; + } + + // TODO Will eventually create the other methods that are included in the Public API. + private Coin ParseJsonResponse(string json) { - Coin newCoin = JsonConvert.DeserializeObject(json); + Console.WriteLine(json); + Coin newCoin = JsonSerializer.Deserialize(json); + Console.WriteLine($"New Coin has pcgs number {newCoin.PCGSNo}"); + + string test = JsonSerializer.Serialize(newCoin); + Console.WriteLine(test); + return newCoin; } } \ No newline at end of file diff --git a/PcgsInvUi/ViewModels/DeleteWindowViewModel.cs b/PcgsInvUi/ViewModels/DeleteWindowViewModel.cs new file mode 100644 index 0000000..d25afba --- /dev/null +++ b/PcgsInvUi/ViewModels/DeleteWindowViewModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Reactive; +using System.Windows.Input; +using System.Xml; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using ReactiveUI; + +namespace PcgsInvUi.ViewModels; + +public class DeleteWindowViewModel : ViewModelBase +{ + public ReactiveCommand OkCommand { get; } = ReactiveCommand.Create(() => (object)true); + public ReactiveCommand CancelCommand { get; } = ReactiveCommand.Create(() => (object)false); +} \ No newline at end of file diff --git a/PcgsInvUi/ViewModels/EditViewModel.cs b/PcgsInvUi/ViewModels/EditViewModel.cs index a8b1fd5..836e354 100644 --- a/PcgsInvUi/ViewModels/EditViewModel.cs +++ b/PcgsInvUi/ViewModels/EditViewModel.cs @@ -16,10 +16,10 @@ public class EditViewModel : ViewModelBase CurrentCoin = coin; var okEnabled = this.WhenAnyValue( - x => x.CurrentCoin.PcgsNumber, + x => x.CurrentCoin.PCGSNo, x => x.CurrentCoin.Grade, x => x.CurrentCoin.Quantity, - (id, grade, quantity) => (id != 0) && + (id, grade, quantity) => !string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(grade) && (quantity != 0) ); diff --git a/PcgsInvUi/ViewModels/MainWindowViewModel.cs b/PcgsInvUi/ViewModels/MainWindowViewModel.cs index 03f7d71..c73261c 100644 --- a/PcgsInvUi/ViewModels/MainWindowViewModel.cs +++ b/PcgsInvUi/ViewModels/MainWindowViewModel.cs @@ -1,7 +1,7 @@ using System; -using System.Reactive.Linq; using System.Collections.ObjectModel; -using System.Collections.Specialized; +using System.Reactive.Linq; +using System.Windows.Input; using PcgsInvUi.Models; using PcgsInvUi.Services; using ReactiveUI; @@ -10,11 +10,6 @@ namespace PcgsInvUi.ViewModels; public class MainWindowViewModel : ViewModelBase { - public bool PaneOpen - { - get => _paneOpen; - set => this.RaiseAndSetIfChanged(ref _paneOpen, value); - } public ViewModelBase SidebarContent { get => _sideContent; @@ -31,54 +26,39 @@ public class MainWindowViewModel : ViewModelBase get => _totalValue; set => this.RaiseAndSetIfChanged(ref _totalValue, value); } + public ICommand DeleteCommand { get; } + public Interaction ShowDeleteWindow { get; } private ViewModelBase? _sideContent; private Coin? _selectedCoin; - private bool _paneOpen; private double _totalValue; + private PcgsClient _pcgsClient; public MainWindowViewModel(CoinCollection coins) - { - CoinCollection = new ObservableCollection(coins.GetItems()); - } - - public void AddItem() { var newViewModel = new NewViewModel(); - - Observable.Merge( - newViewModel.OkCommand, - newViewModel.CancelCommand.Select(_ => (Coin?)null)) - .Take(1) - .Subscribe(newCoin => - { - if (newCoin != null) - { - // This raises a CollectionChanged event, which *should* update the UI, but doesn't. - CoinCollection.Add(newCoin); - // Update view - TotalValue += newCoin.TotalPrice; - - // Setting main content to null and then back to the main view model works just fine. - // TotalValue updates just fine. - } - - SidebarContent = null; - PaneOpen = false; - }); - SidebarContent = newViewModel; - PaneOpen = true; - } - - public void EditItem() - { - var editViewModel = new EditViewModel(SelectedCoin); - } - - public void DeleteItem() - { + CoinCollection = new ObservableCollection(coins.GetItems()); + _pcgsClient = new PcgsClient("eAb8gS0I2XAvT_5gJeiGJaglMia1Tk-oB4kJUK6kuafyrny_S61vIJY-Ikl4nCQM67wrdxzUqLVWTV2kBSxD3d5XNBHxHnYBhcSS6dOPug0hZaF3qAv56df3gYSzOGh9Tif5y0eP3Iw0LrqKDr1Hj-dk6SV6GKog2IIqCPQhhHH8FMTWBTYO-_O8cx7qLdM5GM8KlTsic6g3VRUhM8EA_4OO04dCfmNLGhqINRl3jGZ0Q4ziI8fng2bVWsIyteqiPzUn10rIQ3-OPpqVZG_DxeOmOejj4GzbUNyqUOajy-nr5rYY"); + ShowDeleteWindow = new Interaction(); + DeleteCommand = ReactiveCommand.CreateFromTask(async () => + { + var deleteViewModel = new DeleteWindowViewModel(); + var result = await ShowDeleteWindow.Handle(deleteViewModel); + if (result) CoinCollection.Remove(SelectedCoin); + }); + + // Subscribe to SidebarContent.OkCommand, which is an IObservable<(int, string, int)> + // This is the same as the above, but with a different syntax. + newViewModel.OkCommand + .Subscribe(async requestStructure => + { + var newCoin = await _pcgsClient.GetCoinFactsByGrade(requestStructure.Item1, requestStructure.Item2); + newCoin.Quantity = requestStructure.Item3; + CoinCollection.Add(newCoin); + TotalValue += newCoin.Quantity * newCoin.PriceGuideValue; + }); } public void FindItem() diff --git a/PcgsInvUi/ViewModels/NewViewModel.cs b/PcgsInvUi/ViewModels/NewViewModel.cs index 04bd215..82cc959 100644 --- a/PcgsInvUi/ViewModels/NewViewModel.cs +++ b/PcgsInvUi/ViewModels/NewViewModel.cs @@ -1,16 +1,14 @@ -using System; -using System.Reactive; +using System.Reactive; using System.Collections.Generic; -using PcgsInvUi.Models; using ReactiveUI; namespace PcgsInvUi.ViewModels; public class NewViewModel : ViewModelBase { - private string _pcgsNumber; - private string _grade; - private string _quantity; + private string _pcgsNumber = ""; + private string _grade = ""; + private string _quantity = ""; public string PcgsNumber { @@ -40,15 +38,23 @@ public class NewViewModel : ViewModelBase !string.IsNullOrWhiteSpace(quantity)); // This will eventually send our request to the public API, then construct our coin. + // OkCommand = ReactiveCommand.Create( + // () => new Coin { PcgsNumber = Int32.Parse(PcgsNumber), + // Grade = Grade, + // Quantity = Int32.Parse(Quantity) + // }, + // okEnabled); + OkCommand = ReactiveCommand.Create( - () => new Coin { PcgsNumber = Int32.Parse(PcgsNumber), - Grade = Grade, - Quantity = Int32.Parse(Quantity), - PriceGuideValue = 100.0 - }, + () => (int.Parse(PcgsNumber), Grade, int.Parse(Quantity)), okEnabled); - CancelCommand = ReactiveCommand.Create(() => { }); + ClearCommand = ReactiveCommand.Create(() => + { + PcgsNumber = ""; + Grade = ""; + Quantity = ""; + }); // Initialize grade values for use in the view. // This must be typed out manually, as there is no way to get a list of grades from the API. @@ -86,8 +92,8 @@ public class NewViewModel : ViewModelBase "MS-70" }; } - - public ReactiveCommand OkCommand { get; } - public ReactiveCommand CancelCommand { get; } + + public ReactiveCommand OkCommand { get; } + public ReactiveCommand ClearCommand { get; } } \ No newline at end of file diff --git a/PcgsInvUi/Views/DeleteWindow.axaml b/PcgsInvUi/Views/DeleteWindow.axaml index 45b268d..9571f7a 100644 --- a/PcgsInvUi/Views/DeleteWindow.axaml +++ b/PcgsInvUi/Views/DeleteWindow.axaml @@ -1,9 +1,9 @@  @@ -14,11 +14,11 @@ Width="100" HorizontalAlignment="Stretch" VerticalAlignment="Center" HorizontalContentAlignment="Center" - Content="Yes" Click="AcceptClicked"/> + Content="Yes" Command="{Binding OkCommand}"/>