mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
WIP modlist contents viewer
This commit is contained in:
parent
7e29706b38
commit
5051e800b4
@ -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
|
||||
{
|
||||
@ -80,6 +82,40 @@ using Wabbajack.Lib.Downloaders;
|
||||
}
|
||||
}
|
||||
|
||||
[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 ClientAPI
|
||||
{
|
||||
public static async Task<Wabbajack.Lib.Http.Client> GetClient()
|
||||
@ -298,5 +334,14 @@ using Wabbajack.Lib.Downloaders;
|
||||
$"{Consts.WabbajackBuildServerUri}game_files");
|
||||
return results;
|
||||
}
|
||||
|
||||
public static async Task<DetailedStatus> GetDetailedStatus(string machineURL)
|
||||
{
|
||||
var client = await GetClient();
|
||||
var results =
|
||||
await client.GetJsonAsync<DetailedStatus>(
|
||||
$"{Consts.WabbajackBuildServerUri}lists/status/{machineURL}.json");
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -39,6 +39,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;
|
||||
@ -90,6 +92,15 @@ namespace Wabbajack
|
||||
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}")));
|
||||
ModListContentsCommend = ReactiveCommand.Create(async () =>
|
||||
{
|
||||
_parent.MWVM.ModListContentsVM.Value.Name = metadata.Title;
|
||||
var status = await ClientAPI.GetDetailedStatus(metadata.Links.MachineURL);
|
||||
var coll = _parent.MWVM.ModListContentsVM.Value.Status;
|
||||
coll.Clear();
|
||||
coll.AddRange(status.Archives);
|
||||
_parent.MWVM.NavigateTo(_parent.MWVM.ModListContentsVM.Value);
|
||||
});
|
||||
ExecuteCommand = ReactiveCommand.CreateFromObservable<Unit, Unit>(
|
||||
canExecute: this.WhenAny(x => x.IsBroken).Select(x => !x),
|
||||
execute: (unit) =>
|
||||
@ -177,6 +188,8 @@ namespace Wabbajack
|
||||
.ToGuiProperty(this, nameof(LoadingImage));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task<bool> Download()
|
||||
{
|
||||
ProgressPercent = Percent.Zero;
|
||||
|
@ -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
|
||||
|
72
Wabbajack/View Models/ModListContentsVM.cs
Normal file
72
Wabbajack/View Models/ModListContentsVM.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack.Lib;
|
||||
using ReactiveUI;
|
||||
using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
public class ModListContentsVM : ViewModel
|
||||
{
|
||||
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)
|
||||
{
|
||||
_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.ToFileSizeString(),
|
||||
Url = a.Url ?? "",
|
||||
Downloader = TransformClassName(a.Archive) ?? "Unknown",
|
||||
Hash = a.Archive!.Hash.ToBase64()
|
||||
})
|
||||
.Bind(out _archives)
|
||||
.Subscribe()
|
||||
.DisposeWith(CompositeDisposable);
|
||||
}
|
||||
}
|
||||
|
||||
public class ModListArchive
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Size { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Downloader { get; set; }
|
||||
public string Hash { get; set; }
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
||||
|
66
Wabbajack/Views/ModListContentsView.xaml
Normal file
66
Wabbajack/Views/ModListContentsView.xaml
Normal file
@ -0,0 +1,66 @@
|
||||
<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="300"
|
||||
VerticalContentAlignment="Center" />
|
||||
<Button
|
||||
x:Name="ClearFiltersButton"
|
||||
Margin="0,0,10,0"
|
||||
Style="{StaticResource IconBareButtonStyle}"
|
||||
ToolTip="Clear All Filters">
|
||||
<iconPacks:Material Kind="FilterRemove" />
|
||||
</Button>
|
||||
</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}"></DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Downloader" Binding="{Binding Downloader}"></DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Size" Binding="{Binding Size}"></DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Hash" Binding="{Binding Hash}"></DataGridTextColumn>
|
||||
<DataGridHyperlinkColumn Header="Link" Binding="{Binding Url}"></DataGridHyperlinkColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
</Grid>
|
||||
</rxui:ReactiveUserControl>
|
47
Wabbajack/Views/ModListContentsView.xaml.cs
Normal file
47
Wabbajack/Views/ModListContentsView.xaml.cs
Normal file
@ -0,0 +1,47 @@
|
||||
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 =>
|
||||
{
|
||||
/*
|
||||
var queryText = this
|
||||
.WhenAny(x => x.SearchBox)
|
||||
.Select(t => t.Text)
|
||||
.StartWith("")
|
||||
.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.ContainsCaseInsensitive(s) ||
|
||||
ar.Url.ContainsCaseInsensitive(s));
|
||||
*/
|
||||
this.ArchiveGrid.ItemsSource = this.ViewModel.Archives;
|
||||
|
||||
this.WhenAny(x => x.ViewModel.Name)
|
||||
.BindToStrict(this, x => x.ModListTitle.Title)
|
||||
.DisposeWith(disposable);
|
||||
/*this.WhenAny(x => x.ViewModel.Archives)
|
||||
.BindToStrict(this, x => x.ArchiveGrid.ItemsSource)
|
||||
.DisposeWith(disposable);*/
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@
|
||||
FontSize="14"
|
||||
TextWrapping="Wrap" />
|
||||
</ScrollViewer>
|
||||
<ItemsControl Grid.Row="2" Grid.ColumnSpan="2" ItemsSource="{Binding ModListTagList}">
|
||||
<ItemsControl Grid.Row="2" ItemsSource="{Binding ModListTagList}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel/>
|
||||
@ -285,29 +285,42 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<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">
|
||||
@ -354,6 +367,7 @@
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user