Merge pull request #1429 from wabbajack-tools/filter-gallery

Filter gallery and Tag Searching
This commit is contained in:
Timothy Baldridge 2021-04-29 06:29:36 -07:00 committed by GitHub
commit c04425f149
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 380 additions and 56 deletions

View File

@ -1,6 +1,11 @@
### Changelog
#### Version - 2.4.3.3 - 4/12/2021
#### Version - 2.4.4.0 - 4/28/2021
* Search by tags in the gallery view
* Moved tags to a place where they won't break the UI so much if we have a lot of them
* Added a modlist contents viewer (does not require downloading the modlist)
#### Version - 2.4.3.3 - 4/13/2021
* Default to a "Wabbajack" user agent when making HTTP calls
* Some niceties for Mod authors uploading to our CDN
* upgrade several external dependencies

View File

@ -6,8 +6,8 @@
<AssemblyName>wabbajack-cli</AssemblyName>
<Company>Wabbajack</Company>
<Platforms>x64</Platforms>
<AssemblyVersion>2.4.3.3</AssemblyVersion>
<FileVersion>2.4.3.3</FileVersion>
<AssemblyVersion>2.4.4.0</AssemblyVersion>
<FileVersion>2.4.4.0</FileVersion>
<Copyright>Copyright © 2019-2020</Copyright>
<Description>An automated ModList installer</Description>
<PublishReadyToRun>true</PublishReadyToRun>

View File

@ -49,7 +49,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Genbox.AlphaFS" Version="2.2.2.1" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.32" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.33" />
<PackageReference Include="ini-parser-netstandard" Version="2.5.2" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />

View File

@ -4,8 +4,8 @@
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<AssemblyVersion>2.4.3.3</AssemblyVersion>
<FileVersion>2.4.3.3</FileVersion>
<AssemblyVersion>2.4.4.0</AssemblyVersion>
<FileVersion>2.4.4.0</FileVersion>
<Copyright>Copyright © 2019-2020</Copyright>
<Description>Wabbajack Application Launcher</Description>
<PublishReadyToRun>true</PublishReadyToRun>

View File

@ -8,12 +8,14 @@ using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using K4os.Compression.LZ4.Internal;
using Newtonsoft.Json;
using Org.BouncyCastle.Crypto.Agreement.Srp;
using Wabbajack.Common;
using Wabbajack.Common.Exceptions;
using Wabbajack.Common.Serialization.Json;
using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.LibCefHelpers;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack.Lib
{

View File

@ -25,7 +25,7 @@
<Version>2.2.2.1</Version>
</PackageReference>
<PackageReference Include="HtmlAgilityPack">
<Version>1.11.32</Version>
<Version>1.11.33</Version>
</PackageReference>
<PackageReference Include="MegaApiClient">
<Version>1.9.0</Version>
@ -43,7 +43,7 @@
<Version>13.2.18</Version>
</PackageReference>
<PackageReference Include="SharpCompress">
<Version>0.28.1</Version>
<Version>0.28.2</Version>
</PackageReference>
<PackageReference Include="System.Collections.Immutable">
<Version>5.0.0</Version>

View File

@ -14,6 +14,7 @@ using Wabbajack.Server;
using Wabbajack.Server.DataLayer;
using Wabbajack.Server.DTOs;
using Wabbajack.Server.Services;
using ArchiveStatus = Wabbajack.Server.DTOs.ArchiveStatus;
namespace Wabbajack.BuildServer.Controllers
{

View File

@ -13,6 +13,7 @@ using Wabbajack.Lib.ModListRegistry;
using Wabbajack.Lib.NexusApi;
using Wabbajack.Server.DataLayer;
using Wabbajack.Server.DTOs;
using ArchiveStatus = Wabbajack.Server.DTOs.ArchiveStatus;
namespace Wabbajack.Server.Services
{

View File

@ -3,8 +3,8 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<AssemblyVersion>2.4.3.3</AssemblyVersion>
<FileVersion>2.4.3.3</FileVersion>
<AssemblyVersion>2.4.4.0</AssemblyVersion>
<FileVersion>2.4.4.0</FileVersion>
<Copyright>Copyright © 2019-2020</Copyright>
<Description>Wabbajack Server</Description>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
@ -16,7 +16,7 @@
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.78" />
<PackageReference Include="Discord.Net.WebSocket" Version="2.3.1" />
<PackageReference Include="FluentFTP" Version="33.1.5" />
<PackageReference Include="FluentFTP" Version="33.1.8" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

View File

@ -17,7 +17,7 @@
<PackageReference Include="Genbox.AlphaFS" Version="2.2.2.1" />
<PackageReference Include="K4os.Hash.Crc" Version="1.1.4" />
<PackageReference Include="OMODFramework" Version="3.0.1" />
<PackageReference Include="SharpCompress" Version="0.28.1" />
<PackageReference Include="SharpCompress" Version="0.28.2" />
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -141,6 +141,11 @@ Global
{BA8A3E49-60D2-4BA2-B285-CB09FFDB6D32}.Release|Any CPU.ActiveCfg = Release|x64
{BA8A3E49-60D2-4BA2-B285-CB09FFDB6D32}.Release|x64.ActiveCfg = Release|x64
{BA8A3E49-60D2-4BA2-B285-CB09FFDB6D32}.Release|x64.Build.0 = Release|x64
{44E30B97-D4A8-40A6-81D5-5CAB1F3D45CB}.Debug|Any CPU.ActiveCfg = Debug|x64
{44E30B97-D4A8-40A6-81D5-5CAB1F3D45CB}.Debug|x64.ActiveCfg = Debug|x64
{44E30B97-D4A8-40A6-81D5-5CAB1F3D45CB}.Debug|x64.Build.0 = Debug|x64
{44E30B97-D4A8-40A6-81D5-5CAB1F3D45CB}.Release|Any CPU.ActiveCfg = Release|x64
{44E30B97-D4A8-40A6-81D5-5CAB1F3D45CB}.Release|x64.ActiveCfg = Release|x64
{3E11B700-8405-433D-BF47-6C356087A7C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E11B700-8405-433D-BF47-6C356087A7C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E11B700-8405-433D-BF47-6C356087A7C2}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -157,7 +162,6 @@ Global
{9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}.Release|Any CPU.Build.0 = Release|Any CPU
{9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}.Release|x64.ActiveCfg = Release|Any CPU
{9DEC8DC8-B6E0-469B-9571-C4BAC0776D07}.Release|x64.Build.0 = Release|Any CPU
{44E30B97-D4A8-40A6-81D5-5CAB1F3D45CB}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Wabbajack.Common;
using Wabbajack.Common.Serialization.Json;
using Wabbajack.Lib;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack
{
[JsonName("DetailedStatus")]
public class DetailedStatus
{
public string Name { get; set; } = "";
public DateTime Checked { get; set; } = DateTime.UtcNow;
public List<DetailedStatusItem> Archives { get; set; } = new();
public DownloadMetadata DownloadMetaData { get; set; } = new();
public bool HasFailures { get; set; }
public string MachineName { get; set; } = "";
}
[JsonName("DetailedStatusItem")]
public class DetailedStatusItem
{
public bool IsFailing { get; set; }
public Archive Archive { get; set; }
public string Name => string.IsNullOrWhiteSpace(Archive!.Name) ? Archive.State.PrimaryKeyString : Archive.Name;
public string Url => Archive?.State.GetManifestURL(Archive!);
[JsonIgnore]
public bool HasUrl => Url != null;
public ArchiveStatus ArchiveStatus { get; set; }
}
public enum ArchiveStatus
{
Valid,
InValid,
Updating,
Updated,
Mirrored
}
public class ClientAPIEx
{
public static async Task<DetailedStatus> GetDetailedStatus(string machineURL)
{
var client = await ClientAPI.GetClient();
var results =
await client.GetJsonAsync<DetailedStatus>(
$"{Consts.WabbajackBuildServerUri}lists/status/{machineURL}.json");
return results;
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Globalization;
using System.Windows.Data;
using Wabbajack.Common;
namespace Wabbajack
{
public class FileSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((long)value).ToFileSizeString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -18,6 +18,7 @@
<local:EqualsToBoolConverter x:Key="EqualsToBoolConverter" />
<local:IsTypeVisibilityConverter x:Key="IsTypeVisibilityConverter" />
<local:AbsolutePathToStringConverter x:Key="AbsolutePathToStringConverter" />
<local:FileSizeConverter x:Key="FileSizeConverter"/>
<!-- Colors -->
<Color x:Key="WindowBackgroundColor">#121212</Color>

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
@ -144,7 +145,7 @@ namespace Wabbajack
.Select<string, Func<ModListMetadataVM, bool>>(search => (vm) =>
{
if (string.IsNullOrWhiteSpace(search)) return true;
return vm.Metadata.Title.ContainsCaseInsensitive(search);
return vm.Metadata.Title.ContainsCaseInsensitive(search) || vm.Metadata.tags.Any(t => t.ContainsCaseInsensitive(search));
}))
.Filter(this.WhenAny(x => x.ShowNSFW)
.Select<bool, Func<ModListMetadataVM, bool>>(showNSFW => vm =>

View File

@ -5,12 +5,14 @@ using System.Linq;
using System.Net;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Alphaleonis.Win32.Filesystem;
using DynamicData;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Wabbajack.Common;
@ -39,6 +41,8 @@ namespace Wabbajack
public ICommand OpenWebsiteCommand { get; }
public ICommand ExecuteCommand { get; }
public ICommand ModListContentsCommend { get; }
private readonly ObservableAsPropertyHelper<bool> _Exists;
public bool Exists => _Exists.Value;
@ -71,21 +75,46 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<bool> _LoadingImage;
public bool LoadingImage => _LoadingImage.Value;
private Subject<bool> IsLoadingIdle;
public ModListMetadataVM(ModListGalleryVM parent, ModlistMetadata metadata)
{
_parent = parent;
Metadata = metadata;
Location = LauncherUpdater.CommonFolder.Value.Combine("downloaded_mod_lists", Metadata.Links.MachineURL + (string)Consts.ModListExtension);
ModListTagList = new List<ModListTag>();
Metadata.tags.ForEach(tag =>
{
ModListTagList.Add(new ModListTag(tag));
});
ModListTagList.Add(new ModListTag(metadata.Game.MetaData().HumanFriendlyGameName));
DownloadSizeText = "Download size : " + UIUtils.FormatBytes(Metadata.DownloadMetadata.SizeOfArchives);
InstallSizeText = "Installation size : " + UIUtils.FormatBytes(Metadata.DownloadMetadata.SizeOfInstalledFiles);
IsBroken = metadata.ValidationSummary.HasFailures || metadata.ForceDown;
//https://www.wabbajack.org/#/modlists/info?machineURL=eldersouls
OpenWebsiteCommand = ReactiveCommand.Create(() => Utils.OpenWebsite(new Uri($"https://www.wabbajack.org/#/modlists/info?machineURL={Metadata.Links.MachineURL}")));
IsLoadingIdle = new Subject<bool>();
ModListContentsCommend = ReactiveCommand.Create(async () =>
{
_parent.MWVM.ModListContentsVM.Value.Name = metadata.Title;
IsLoadingIdle.OnNext(false);
try
{
var status = await ClientAPIEx.GetDetailedStatus(metadata.Links.MachineURL);
var coll = _parent.MWVM.ModListContentsVM.Value.Status;
coll.Clear();
coll.AddRange(status.Archives);
_parent.MWVM.NavigateTo(_parent.MWVM.ModListContentsVM.Value);
}
finally
{
IsLoadingIdle.OnNext(true);
}
}, IsLoadingIdle.StartWith(true));
ExecuteCommand = ReactiveCommand.CreateFromObservable<Unit, Unit>(
canExecute: this.WhenAny(x => x.IsBroken).Select(x => !x),
execute: (unit) =>
@ -173,6 +202,8 @@ namespace Wabbajack
.ToGuiProperty(this, nameof(LoadingImage));
}
private async Task<bool> Download()
{
ProgressPercent = Percent.Zero;

View File

@ -41,6 +41,7 @@ namespace Wabbajack
public readonly Lazy<SettingsVM> SettingsPane;
public readonly Lazy<ModListGalleryVM> Gallery;
public readonly ModeSelectionVM ModeSelectionVM;
public readonly Lazy<ModListContentsVM> ModListContentsVM;
public readonly UserInterventionHandlers UserInterventionHandlers;
public ICommand CopyVersionCommand { get; }
@ -62,6 +63,7 @@ namespace Wabbajack
SettingsPane = new Lazy<SettingsVM>(() => new SettingsVM(this));
Gallery = new Lazy<ModListGalleryVM>(() => new ModListGalleryVM(this));
ModeSelectionVM = new ModeSelectionVM(this);
ModListContentsVM = new Lazy<ModListContentsVM>(() => new ModListContentsVM(this));
UserInterventionHandlers = new UserInterventionHandlers(this);
// Set up logging

View File

@ -0,0 +1,79 @@
using System;
using System.Collections.ObjectModel;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using ReactiveUI.Fody.Helpers;
using Wabbajack.Lib;
using DynamicData;
using DynamicData.Binding;
namespace Wabbajack
{
public class ModListContentsVM : BackNavigatingVM
{
private MainWindowVM _mwvm;
[Reactive]
public string Name { get; set; }
[Reactive]
public ObservableCollection<DetailedStatusItem> Status { get; set; }
[Reactive]
public string SearchString { get; set; }
private readonly ReadOnlyObservableCollection<ModListArchive> _archives;
public ReadOnlyObservableCollection<ModListArchive> Archives => _archives;
public ModListContentsVM(MainWindowVM mwvm) : base(mwvm)
{
_mwvm = mwvm;
Status = new ObservableCollectionExtended<DetailedStatusItem>();
Regex nameMatcher = new Regex(@"(?<=\.)[^\.]+(?=\+State)");
string TransformClassName(Archive a)
{
var cname = a.State.GetType().FullName;
if (cname == null) return null;
var match = nameMatcher.Match(cname);
return match.Success ? match.ToString() : null;
}
this.Status
.ToObservableChangeSet()
.Transform(a => new ModListArchive
{
Name = a.Name,
Size = a.Archive?.Size ?? 0,
Url = a.Url ?? "",
Downloader = TransformClassName(a.Archive) ?? "Unknown",
Hash = a.Archive!.Hash.ToBase64()
})
.Filter(this.WhenAny(x => x.SearchString)
.StartWith("")
.Throttle(TimeSpan.FromMilliseconds(250))
.Select<string, Func<ModListArchive, bool>>(s => (ModListArchive ar) =>
string.IsNullOrEmpty(s) ||
ar.Name.ContainsCaseInsensitive(s) ||
ar.Downloader.ContainsCaseInsensitive(s) ||
ar.Hash.ContainsCaseInsensitive(s) ||
ar.Size.ToString() == s ||
ar.Url.ContainsCaseInsensitive(s)))
.ObserveOnGuiThread()
.Bind(out _archives)
.Subscribe()
.DisposeWith(CompositeDisposable);
}
}
public class ModListArchive
{
public string Name { get; set; }
public long Size { get; set; }
public string Url { get; set; }
public string Downloader { get; set; }
public string Hash { get; set; }
}
}

View File

@ -40,6 +40,9 @@
<DataTemplate DataType="{x:Type local:SettingsVM}">
<local:SettingsView ViewModel="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ModListContentsVM}">
<local:ModListContentsView ViewModel="{Binding}" />
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>

View File

@ -0,0 +1,59 @@
<rxui:ReactiveUserControl
x:Class="Wabbajack.ModListContentsView"
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:Wabbajack"
xmlns:rxui="http://reactiveui.net"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
x:TypeArguments="local:ModListContentsVM"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="47"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<local:TopProgressView Grid.Row="0" Grid.RowSpan="2"
x:Name="ModListTitle"
ShadowMargin="False" />
<WrapPanel Grid.Row="0"
Height="25"
Margin="5,5,5,10"
HorizontalAlignment="Right"
Orientation="Horizontal">
<TextBlock
Margin="0,0,5,0"
VerticalAlignment="Center"
Foreground="{StaticResource ForegroundBrush}"
Text="Search" />
<TextBox
x:Name="SearchBox"
Width="400"
VerticalContentAlignment="Center" />
</WrapPanel>
<Button Grid.Row="0"
x:Name="BackButton"
Width="30"
Height="30"
Margin="7,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Style="{StaticResource IconCircleButtonStyle}"
ToolTip="Back to main menu">
<iconPacks:PackIconMaterial Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Kind="ArrowLeft" />
</Button>
<DataGrid Grid.Row="1" x:Name="ArchiveGrid" AutoGenerateColumns="False" AlternatingRowBackground="#131313" FontSize="14">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Downloader" Binding="{Binding Downloader}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Size" Binding="{Binding Size, Converter={StaticResource FileSizeConverter}}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Hash" Binding="{Binding Hash}" IsReadOnly="True"></DataGridTextColumn>
<DataGridHyperlinkColumn Header="Link" Binding="{Binding Url}" IsReadOnly="True"></DataGridHyperlinkColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</rxui:ReactiveUserControl>

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows.Controls;
using System.Windows.Xps;
using ReactiveUI;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI.Fody.Helpers;
namespace Wabbajack
{
public partial class ModListContentsView
{
public ModListContentsView()
{
InitializeComponent();
this.WhenActivated(disposable =>
{
this.ArchiveGrid.ItemsSource = this.ViewModel.Archives;
this.WhenAny(x => x.ViewModel.Name)
.BindToStrict(this, x => x.ModListTitle.Title)
.DisposeWith(disposable);
this.BindStrict(ViewModel, x => x.SearchString, x => x.SearchBox.Text)
.DisposeWith(disposable);
this.WhenAny(x => x.ViewModel.BackCommand)
.BindToStrict(this, x => x.BackButton.Command)
.DisposeWith(disposable);
});
}
}
}

View File

@ -69,11 +69,12 @@
</Border.Style>
<Grid
Width="570"
Height="440"
Height="480"
Background="{StaticResource DarkBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
@ -143,28 +144,6 @@
</Style>
</Ellipse.Style>
</Ellipse>
<ItemsControl ItemsSource="{Binding ModListTagList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Grid.Row="0" Grid.ColumnSpan="2"
Margin="10,5,0,5"
Background="{StaticResource Analogous1Brush}"
BorderThickness="1"
CornerRadius="7,7,7,7"
Opacity="0.90">
<TextBlock
Margin="5,5,5,5"
FontSize="15"
Text="{Binding Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Label
Margin="10,257,0,0"
HorizontalAlignment="Left"
@ -275,35 +254,73 @@
Foreground="{StaticResource SecondaryBrush}"
Maximum="1"
Visibility="{Binding IsEnabled, ElementName=ExecuteButton, Converter={StaticResource bool2VisibilityHiddenConverter}, ConverterParameter=False}" />
<TextBlock Grid.Row="1" Grid.Column="0"
x:Name="MetadataDescription"
Margin="8,5"
VerticalAlignment="Center"
FontSize="14"
TextWrapping="Wrap" />
<Grid Grid.Row="1" Grid.Column="1">
<ScrollViewer Grid.Row="1" Grid.Column="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<TextBlock
x:Name="MetadataDescription"
Margin="8,5"
VerticalAlignment="Center"
FontSize="14"
TextWrapping="Wrap" />
</ScrollViewer>
<ItemsControl Grid.Row="2" ItemsSource="{Binding ModListTagList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Grid.Row="0" Grid.ColumnSpan="2"
Margin="5,5,0,5"
Background="{StaticResource Analogous1Brush}"
BorderThickness="1"
CornerRadius="7,7,7,7"
VerticalAlignment="Center"
Opacity="0.90">
<TextBlock
Margin="5,5,5,5"
FontSize="15"
Text="{Binding Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid Grid.Row="1" Grid.Column="1" Grid.RowSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Row="0"
x:Name="OpenWebsiteButton"
Width="40"
Height="40"
Margin="5,0"
VerticalAlignment="Bottom"
Style="{StaticResource IconBareButtonStyle}">
x:Name="OpenWebsiteButton"
Width="40"
Height="40"
Margin="5,0"
VerticalAlignment="Center"
Style="{StaticResource IconBareButtonStyle}">
<iconPacks:Material
Width="20"
Height="20"
Kind="Web" />
</Button>
<Button Grid.Row="1"
x:Name="ModListContentsButton"
Width="40"
Height="40"
Margin="5,0"
VerticalAlignment="Center"
Style="{StaticResource IconBareButtonStyle}">
<iconPacks:Material
Width="20"
Height="20"
Kind="TableSearch" />
</Button>
<Button Grid.Row="2"
x:Name="ExecuteButton"
Width="40"
Height="40"
Margin="5,0"
VerticalAlignment="Top">
VerticalAlignment="Center">
<Button.Style>
<Style BasedOn="{StaticResource IconBareButtonStyle}" TargetType="Button">
<Setter Property="Content">
@ -350,6 +367,7 @@
</Style>
</Button.Style>
</Button>
</Grid>
</Grid>
</Border>

View File

@ -59,6 +59,9 @@ namespace Wabbajack
this.WhenAny(x => x.ViewModel.OpenWebsiteCommand)
.BindToStrict(this, x => x.OpenWebsiteButton.Command)
.DisposeWith(dispose);
this.WhenAny(x => x.ViewModel.ModListContentsCommend)
.BindToStrict(this, x => x.ModListContentsButton.Command)
.DisposeWith(dispose);
this.WhenAny(x => x.ViewModel.ExecuteCommand)
.BindToStrict(this, x => x.ExecuteButton.Command)
.DisposeWith(dispose);

View File

@ -6,8 +6,8 @@
<UseWPF>true</UseWPF>
<Platforms>x64</Platforms>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<AssemblyVersion>2.4.3.3</AssemblyVersion>
<FileVersion>2.4.3.3</FileVersion>
<AssemblyVersion>2.4.4.0</AssemblyVersion>
<FileVersion>2.4.4.0</FileVersion>
<Copyright>Copyright © 2019-2020</Copyright>
<Description>An automated ModList installer</Description>
<PublishReadyToRun>true</PublishReadyToRun>
@ -55,7 +55,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="cef.redist.x64" Version="89.0.17" />
<PackageReference Include="cef.redist.x64" Version="90.5.7" />
<PackageReference Include="CefSharp.Common" Version="89.0.170" />
<PackageReference Include="CefSharp.Wpf" Version="89.0.170" />
<PackageReference Include="DynamicData" Version="7.1.1" />
@ -69,7 +69,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MahApps.Metro" Version="2.4.4" />
<PackageReference Include="MahApps.Metro" Version="2.4.5" />
<PackageReference Include="MahApps.Metro.IconPacks" Version="4.8.0" />
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
<PackageReference Include="PInvoke.Gdi32" Version="0.7.104" />