Skip to content

Commit

Permalink
Adds "Import Deck" functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ronelm2000 committed Oct 8, 2024
1 parent 44d2eb6 commit 9f10301
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 15 deletions.
66 changes: 66 additions & 0 deletions Montage.Weiss.Tools.GUI/ViewModels/Dialogs/ImportDeckViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using Lamar;
using Montage.Weiss.Tools.CLI;
using Montage.Weiss.Tools.Entities;
using Montage.Weiss.Tools.GUI.Utilities;
using Serilog;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Montage.Weiss.Tools.GUI.ViewModels.Dialogs;
public partial class ImportDeckViewModel : ViewModelBase
{
private static readonly ILogger Log = Serilog.Log.ForContext<ImportDeckViewModel>();

[ObservableProperty]
private bool _isVisible;

[ObservableProperty]
private Func<MainWindowViewModel?> _parent;

[ObservableProperty]
private string deckUrl;

public ImportDeckViewModel()
{
Parent = () => null;
IsVisible = Design.IsDesignMode;
DeckUrl = string.Empty;
}

internal async Task ImportDeck()
{
if (Parent() is not MainWindowViewModel parentModel)
return;
if (parentModel.Container is not IContainer container)
return;

var progressReporter = new ProgressReporter(Log, message => parentModel.Status = message);

var command = new ExportVerb { Source = DeckUrl, NonInteractive = true, NoWarning = true };
var deck = await command.Parse(container, progressReporter);

parentModel.DeckName = deck.Name;
parentModel.DeckRemarks = deck.Remarks;

var cacheList = deck.Ratios.Keys.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom)
.DistinctBy(c => c.ReleaseID)
.Select(c => new CacheVerb { Language = (c.Language == CardLanguage.English ? "en" : "jp"), ReleaseIDorFullSerialID = c.ReleaseID })
.ToList();

foreach (var cacheCommand in cacheList)
await cacheCommand.Run(container, progressReporter);

parentModel.DeckRatioList.Clear();

foreach (var ratio in deck.Ratios)
parentModel.DeckRatioList.Add(new CardRatioViewModel(ratio.Key, ratio.Value));

parentModel.SortDeck();
parentModel.UpdateDeckStats();

IsVisible = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace Montage.Weiss.Tools.GUI.ViewModels;
namespace Montage.Weiss.Tools.GUI.ViewModels.Dialogs;
public partial class ImportSetViewModel : ViewModelBase
{
private static readonly ILogger Log = Serilog.Log.ForContext<ImportSetViewModel>();
Expand All @@ -21,14 +21,14 @@ public partial class ImportSetViewModel : ViewModelBase
private bool _isVisible;

[ObservableProperty]
private Func<MainWindowViewModel?> parent;
private Func<MainWindowViewModel?> _parent;

[ObservableProperty]
private string setUrl;

public ImportSetViewModel()
{
parent = () => null;
Parent = () => null;
IsVisible = Design.IsDesignMode;
SetUrl = string.Empty;
}
Expand All @@ -45,8 +45,6 @@ public async Task ParseSet(CancellationToken token = default)
return;
}

IsVisible = false;

var progressReporter = new ProgressReporter(Log, message => parentViewModel.Status = message);
var command = new ParseVerb {
URI = SetUrl
Expand All @@ -55,6 +53,8 @@ public async Task ParseSet(CancellationToken token = default)

await command.Run(container, progressReporter, token);

IsVisible = false;

void Command_SetParsed(object? sender, string setCode)
{
parentViewModel.SearchBarText = $"set:{setCode}";
Expand Down
20 changes: 18 additions & 2 deletions Montage.Weiss.Tools.GUI/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using JasperFx.Core;
using Montage.Weiss.Tools.GUI.Utilities;
using Montage.Weiss.Tools.GUI.Views;
using Montage.Weiss.Tools.GUI.ViewModels.Dialogs;

namespace Montage.Weiss.Tools.GUI.ViewModels;

Expand All @@ -42,6 +43,7 @@ public partial class MainWindowViewModel : ViewModelBase
public ObservableCollection<CardRatioViewModel> DeckRatioList { get; set; } = [];

public ReactiveCommand<Unit, Unit> ImportSetCommand { get; init; }
public ReactiveCommand<Unit, Unit> ImportDeckCommand { get; init; }
public ReactiveCommand<Unit, Unit> OpenLocalSetCommand { get; init; }
public ReactiveCommand<Unit, Unit> SaveDeckCommand { get; init; }
public ReactiveCommand<Unit, Unit> OpenDeckCommand { get; init; }
Expand All @@ -67,6 +69,9 @@ public partial class MainWindowViewModel : ViewModelBase
[ObservableProperty]
public ImportSetViewModel _importSetDC;

[ObservableProperty]
public ImportDeckViewModel _importDeckDC;

public MainWindowViewModel()
{
Status = "";
Expand Down Expand Up @@ -102,16 +107,19 @@ public MainWindowViewModel()
DeckRatioList.Add(new CardRatioViewModel());
DeckRatioList.Add(new CardRatioViewModel() { Image = new Uri("avares://wsm-gui/Assets/Samples/sample_card.jpg").Load() });
ImportSetDC = new ImportSetViewModel { IsVisible = false, Parent = () => null };
ImportDeckDC = new ImportDeckViewModel { IsVisible = false, Parent = () => null };
}
else
{
DatabaseViewList = [];
ImportSetDC = new ImportSetViewModel { IsVisible = false, Parent = () => this };
ImportDeckDC = new ImportDeckViewModel { IsVisible = false, Parent = () => this };
}

log = Serilog.Log.Logger.ForContext<MainWindowViewModel>();

ImportSetCommand = ReactiveCommand.CreateFromTask(ImportSet);
ImportDeckCommand = ReactiveCommand.CreateFromTask(ImportDeck);
OpenLocalSetCommand = ReactiveCommand.CreateFromTask(OpenLocalSet);
SaveDeckCommand = ReactiveCommand.CreateFromTask(SaveDeck);
OpenDeckCommand = ReactiveCommand.CreateFromTask(OpenDeck);
Expand Down Expand Up @@ -419,6 +427,14 @@ await Dispatcher.UIThread.InvokeAsync(() =>
*/
}

internal async Task ImportDeck()
{
await Dispatcher.UIThread.InvokeAsync(() =>
{
ImportDeckDC.IsVisible = true;
});
}

internal async Task AddCard(WeissSchwarzCard card)
{
var existingRatio = DeckRatioList.Where(crv => crv.Card.Serial == card.Serial).FirstOrDefault();
Expand Down Expand Up @@ -465,7 +481,7 @@ internal async Task RemoveCard(WeissSchwarzCard card)

await ValueTask.CompletedTask;
}
private void SortDeck()
internal void SortDeck()
{
DeckRatioList.SortByDescending(crv => (
level: crv.Card.Level,
Expand All @@ -482,7 +498,7 @@ private void SortDeck()
};
}

private void UpdateDeckStats()
internal void UpdateDeckStats()
{
var totalCards = DeckRatioList.Select(crv => crv.Ratio).Sum();
var totalCharas = DeckRatioList.Where(crv => crv.Card.Type == CardType.Character)
Expand Down
62 changes: 62 additions & 0 deletions Montage.Weiss.Tools.GUI/Views/ImportDeckDialog.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<UserControl 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="800" d:DesignHeight="100"
xmlns:vm="clr-namespace:Montage.Weiss.Tools.GUI.ViewModels.Dialogs;assembly=wsm-gui"
x:Class="Montage.Weiss.Tools.GUI.Views.ImportDeckDialog"
x:DataType="vm:ImportDeckViewModel"
>
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:ImportDeckViewModel />
</Design.DataContext>

<Design.DesignStyle>
<Styles>
<StyleInclude Source="avares://wsm-gui/Styles/Dark.axaml" />
</Styles>
</Design.DesignStyle>

<Border Grid.ColumnSpan="3"
Name="DialogToastBox"
Classes="DialogBox"
VerticalAlignment="Center"
HorizontalAlignment="Center"
IsVisible="{Binding IsVisible}"
>

<StackPanel>
<TextBlock Text="Importing Deck from URL..." Margin="5,5,5,10" />
<TextBox Watermark="Deck URL..."
Text="{Binding DeckUrl}"
MinWidth="400"
/>
<UniformGrid HorizontalAlignment="Stretch"
Columns="2"
Rows="1"
>
<Button MinWidth="200"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Click="CancelButton_Click"
Grid.Column="1"
>
Cancel
</Button>

<Button MinWidth="200"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Click="ParseButton_Click"
Grid.Column="2"
>
Parse
</Button>
</UniformGrid>
</StackPanel>
</Border>
</UserControl>
29 changes: 29 additions & 0 deletions Montage.Weiss.Tools.GUI/Views/ImportDeckDialog.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Montage.Weiss.Tools.GUI.ViewModels.Dialogs;
using System.Threading.Tasks;

namespace Montage.Weiss.Tools.GUI.Views;

public partial class ImportDeckDialog : UserControl
{
public ImportDeckDialog()
{
InitializeComponent();
}

private void CancelButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (DataContext is not ImportDeckViewModel vm)
return;
vm.IsVisible = false;
}

private void ParseButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (DataContext is not ImportDeckViewModel vm)
return;
Task.Run(async () => await vm.ImportDeck());
}
}
4 changes: 2 additions & 2 deletions Montage.Weiss.Tools.GUI/Views/ImportSetDialog.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
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:vm="clr-namespace:Montage.Weiss.Tools.GUI.ViewModels;assembly=wsm-gui"
xmlns:vm="clr-namespace:Montage.Weiss.Tools.GUI.ViewModels.Dialogs;assembly=wsm-gui"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="100"
x:Class="Montage.Weiss.Tools.GUI.Views.ImportSetDialog"
x:DataType="vm:ImportSetViewModel"
Expand All @@ -28,7 +28,7 @@
>

<StackPanel>
<TextBlock Text="Parse Set" Margin="5,5,5,10" />
<TextBlock Text="Importing Set From URL..." Margin="5,5,5,10" />
<TextBox Watermark="Set URL..."
Text="{Binding SetUrl}"
MinWidth="400"
Expand Down
5 changes: 1 addition & 4 deletions Montage.Weiss.Tools.GUI/Views/ImportSetDialog.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using CommandLine;
using Montage.Weiss.Tools.GUI.ViewModels;
using Montage.Weiss.Tools.GUI.ViewModels.Dialogs;
using System.Threading.Tasks;

namespace Montage.Weiss.Tools.GUI.Views;
Expand Down
5 changes: 4 additions & 1 deletion Montage.Weiss.Tools.GUI/Views/MainView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<MenuItem Header="_Open Deck..." Command="{Binding OpenDeckCommand}" />
<MenuItem Header="O_pen Local Set..." Command="{Binding OpenLocalSetCommand}" />
<Separator/>
<MenuItem Header="_Import Deck..." IsEnabled="False" />
<MenuItem Header="_Import Deck..." Command="{Binding ImportDeckCommand}" />
<MenuItem Header="I_mport Set..." Command="{Binding ImportSetCommand}" />
<Separator/>
<MenuItem Header="_Save Deck..." Command="{Binding SaveDeckCommand}"/>
Expand Down Expand Up @@ -155,6 +155,9 @@
<v:ImportSetDialog Name="ImportSetDialog"
DataContext="{Binding ImportSetDC}"
/>
<v:ImportDeckDialog Name="ImportDeckDialog"
DataContext="{Binding ImportDeckDC}"
/>

</Grid>

Expand Down
8 changes: 7 additions & 1 deletion MontageWeissTools/CLI/ExportVerb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,19 @@ public async Task Run(IContainer ioc, IProgress<CommandProgressReport> progress,

Log.Information("Running...");

var deck = await Parse(ioc, deckParserProgress, cancellationToken);
deck = await Run(ioc, deck);
}

public async Task<WeissSchwarzDeck> Parse(IContainer ioc, IProgress<DeckParserProgressReport> deckParserProgress, CancellationToken cancellationToken = default)
{
var parser = await ioc.GetAllInstances<IDeckParser<WeissSchwarzDeck, WeissSchwarzCard>>()
.ToAsyncEnumerable()
.WhereAwait(async parser => await parser.IsCompatible(Source))
.OrderByDescending(parser => parser.Priority)
.FirstAsync(cancellationToken);
var deck = await parser.Parse(Source, deckParserProgress, cancellationToken);
deck = await Run(ioc, deck);
return deck;
}

public async Task<WeissSchwarzDeck> Run(IContainer ioc, WeissSchwarzDeck deck)
Expand Down

0 comments on commit 9f10301

Please sign in to comment.