From cb814c194716ed58763df5d9accd9728d83fc3d5 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 19 Feb 2020 06:42:21 -0700 Subject: [PATCH 1/8] Fix a few bugs with Bethesda.NET downloading --- Wabbajack.Lib/CerasConfig.cs | 3 ++- Wabbajack.Lib/MO2Compiler.cs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Wabbajack.Lib/CerasConfig.cs b/Wabbajack.Lib/CerasConfig.cs index 2c618c13..3b4cb564 100644 --- a/Wabbajack.Lib/CerasConfig.cs +++ b/Wabbajack.Lib/CerasConfig.cs @@ -29,7 +29,8 @@ namespace Wabbajack.Lib typeof(BA2FileEntryState), typeof(MediaFireDownloader.State), typeof(ArchiveMeta), typeof(PropertyFile), typeof(SteamMeta), typeof(SteamWorkshopDownloader), typeof(SteamWorkshopDownloader.State), typeof(LoversLabDownloader.State), typeof(GameFileSourceDownloader.State), typeof(VectorPlexusDownloader.State), - typeof(DeadlyStreamDownloader.State), typeof(AFKModsDownloader.State), typeof(TESAllianceDownloader.State) + typeof(DeadlyStreamDownloader.State), typeof(AFKModsDownloader.State), typeof(TESAllianceDownloader.State), + typeof(BethesdaNetDownloader.State) }, }; Config.VersionTolerance.Mode = VersionToleranceMode.Standard; diff --git a/Wabbajack.Lib/MO2Compiler.cs b/Wabbajack.Lib/MO2Compiler.cs index 567e23c3..093bdfef 100644 --- a/Wabbajack.Lib/MO2Compiler.cs +++ b/Wabbajack.Lib/MO2Compiler.cs @@ -131,7 +131,7 @@ namespace Wabbajack.Lib if (Directory.Exists(ModListOutputFolder)) Utils.DeleteDirectory(ModListOutputFolder); - /* + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Inferring metas for game file downloads"); await InferMetas(); @@ -139,8 +139,8 @@ namespace Wabbajack.Lib if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Reindexing downloads after meta inferring"); await VFS.AddRoot(MO2DownloadsFolder); - await VFS.WriteToFile(_vfsCacheName); - */ + await VFS.WriteToFile(VFSCacheName); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Pre-validating Archives"); From 55ba89b8e08061a2ca0b72787f81466c5f20deb4 Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 15:49:06 +0100 Subject: [PATCH 2/8] Added ChangeDownload CLI Verb --- Wabbajack.CLI/OptionsDefinition.cs | 3 +- Wabbajack.CLI/Program.cs | 1 + Wabbajack.CLI/Verbs/ChangeDownload.cs | 343 ++++++++++++++++++++++++++ 3 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 Wabbajack.CLI/Verbs/ChangeDownload.cs diff --git a/Wabbajack.CLI/OptionsDefinition.cs b/Wabbajack.CLI/OptionsDefinition.cs index 9b1158f7..d6a1db08 100644 --- a/Wabbajack.CLI/OptionsDefinition.cs +++ b/Wabbajack.CLI/OptionsDefinition.cs @@ -12,7 +12,8 @@ namespace Wabbajack.CLI typeof(Validate), typeof(DownloadUrl), typeof(UpdateModlists), - typeof(UpdateNexusCache) + typeof(UpdateNexusCache), + typeof(ChangeDownload) }; } } diff --git a/Wabbajack.CLI/Program.cs b/Wabbajack.CLI/Program.cs index 721b5296..2333371c 100644 --- a/Wabbajack.CLI/Program.cs +++ b/Wabbajack.CLI/Program.cs @@ -15,6 +15,7 @@ namespace Wabbajack.CLI (DownloadUrl opts) => opts.Execute(), (UpdateModlists opts) => opts.Execute(), (UpdateNexusCache opts) => opts.Execute(), + (ChangeDownload opts) => opts.Execute(), errs => 1); } } diff --git a/Wabbajack.CLI/Verbs/ChangeDownload.cs b/Wabbajack.CLI/Verbs/ChangeDownload.cs new file mode 100644 index 00000000..59a82acf --- /dev/null +++ b/Wabbajack.CLI/Verbs/ChangeDownload.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Alphaleonis.Win32.Filesystem; +using CommandLine; +using Wabbajack.Common; +using Wabbajack.Lib; +using Directory = Alphaleonis.Win32.Filesystem.Directory; +using File = Alphaleonis.Win32.Filesystem.File; +using Path = Alphaleonis.Win32.Filesystem.Path; + +namespace Wabbajack.CLI.Verbs +{ + [Verb("change-download", HelpText = "Move or Copy all used Downloads from a Modlist to another directory")] + public class ChangeDownload : AVerb + { + [Option('i', "input", Required = true, HelpText = "Input folder containing the downloads you want to move")] + public string Input { get; set; } + + [Option('o', "output", Required = true, HelpText = "Output folder the downloads should be transferred to")] + public string Output { get; set; } + + [Option("modlist", Required = true, HelpText = "The Modlist, can either be a .wabbajack or a modlist.txt file")] + public string Modlist { get; set; } + + [Option("mods", Required = false, HelpText = "Mods folder location if the provided modlist file is an MO2 modlist.txt")] + public string Mods { get; set; } + + [Option("copy", Default = true, HelpText = "Whether to copy the files")] + public bool Copy { get; set; } + + [Option("move", Default = false, HelpText = "Whether to move the files")] + public bool Move { get; set; } + + [Option("overwrite", Default = false, HelpText = "Whether to overwrite the file if it already exists")] + public bool Overwrite { get; set; } + + [Option("meta", Default = true, HelpText = "Whether to also transfer the meta file for the archive")] + public bool IncludeMeta { get; set; } + + private static void Log(string msg) + { + Console.WriteLine(msg); + } + + private struct TransferFile + { + public readonly string Input; + public readonly string Output; + public readonly bool IsMeta; + + public TransferFile(string input, string output, bool isMeta = false) + { + Input = input; + Output = output; + IsMeta = isMeta; + } + } + + protected override async Task Run() + { + if (!File.Exists(Modlist)) + { + Log($"The file {Modlist} does not exist!"); + return -1; + } + + if (!Directory.Exists(Input)) + { + Log($"The input directory {Input} does not exist!"); + return -1; + } + + if (!Directory.Exists(Output)) + { + Log($"The output directory {Output} does not exist, it will be created."); + Directory.CreateDirectory(Output); + } + + if (!Modlist.EndsWith(Consts.ModListExtension) || !Modlist.EndsWith("modlist.txt")) + { + Log($"The file {Modlist} is not a valid modlist file!"); + return -1; + } + + var isModlist = Modlist.EndsWith(Consts.ModListExtension); + + var list = new List(); + + if (isModlist) + { + ModList modlist; + + try + { + modlist = AInstaller.LoadFromFile(Input); + } + catch (Exception e) + { + Log($"Error while loading the Modlist!\n{e}"); + return 1; + } + + if (modlist == null) + { + Log("The Modlist could not be loaded!"); + return 1; + } + + Log($"Modlist contains {modlist.Archives.Count} archives."); + + modlist.Archives.Do(a => + { + var inputPath = Path.Combine(Input, a.Name); + var outputPath = Path.Combine(Output, a.Name); + + if (!File.Exists(inputPath)) + { + Log($"File {inputPath} does not exist, skipping."); + return; + } + + Log($"Adding {inputPath} to the transfer list."); + list.Add(new TransferFile(inputPath, outputPath)); + + var metaInputPath = Path.Combine(inputPath, ".meta"); + var metaOutputPath = Path.Combine(outputPath, ".meta"); + + if (File.Exists(metaInputPath)) + { + Log($"Found meta file {metaInputPath}"); + if (IncludeMeta) + { + Log($"Adding {metaInputPath} to the transfer list."); + list.Add(new TransferFile(metaInputPath, metaOutputPath)); + } + else + { + Log($"Meta file {metaInputPath} will be ignored."); + } + } + else + { + Log($"Found no meta file for {inputPath}"); + if (IncludeMeta) + { + if (string.IsNullOrWhiteSpace(a.Meta)) + { + Log($"Meta for {a.Name} is empty, this should not be possible but whatever."); + return; + } + + Log("Adding meta from archive info the transfer list"); + list.Add(new TransferFile(a.Meta, metaOutputPath, true)); + } + else + { + Log($"Meta will be ignored for {a.Name}"); + } + } + }); + } + else + { + if (Directory.Exists(Mods)) + { + Log($"Mods directory {Mods} does not exist!"); + return -1; + } + + Log($"Reading modlist.txt from {Modlist}"); + string[] modlist = File.ReadAllLines(Modlist); + + if (modlist == null || modlist.Length == 0) + { + Log($"Provided modlist.txt file at {Modlist} is empty or could not be read!"); + return -1; + } + + var mods = modlist.Where(s => s.StartsWith("+")).Select(s => s.Substring(1)).ToHashSet(); + if (mods.Count == 0) + { + Log("Counted mods from modlist.txt are 0!"); + return -1; + } + + Log($"Found {mods.Count} mods in modlist.txt"); + + var downloads = new HashSet(); + + Directory.EnumerateDirectories(Mods, "*", SearchOption.TopDirectoryOnly) + .Where(d => mods.Contains(Path.GetRelativePath(Path.GetDirectoryName(d), d))) + .Do(d => + { + var meta = Path.Combine(d, "meta.ini"); + if (!File.Exists(meta)) + { + Log($"Mod meta file {meta} does not exist, skipping"); + return; + } + + string[] ini = File.ReadAllLines(meta); + if (ini == null || ini.Length == 0) + { + Log($"Mod meta file {meta} could not be read or is empty!"); + return; + } + + ini.Where(i => !string.IsNullOrWhiteSpace(i) && i.StartsWith("installationFile=")) + .Select(i => i.Replace("installationFile=", "")) + .Do(i => + { + Log($"Found installationFile {i}"); + downloads.Add(i); + }); + }); + + Log($"Found {downloads.Count} installationFiles from mod metas."); + + Directory.EnumerateFiles(Input, "*", SearchOption.TopDirectoryOnly) + .Where(f => downloads.Contains(Path.GetFileNameWithoutExtension(f))) + .Do(f => + { + Log($"Found archive {f}"); + + var outputPath = Path.Combine(Output, Path.GetFileName(f)); + + Log($"Adding {f} to the transfer list"); + list.Add(new TransferFile(f, outputPath)); + + var metaInputPath = Path.Combine(f, ".meta"); + if (File.Exists(metaInputPath)) + { + Log($"Found meta file for {f} at {metaInputPath}"); + if (IncludeMeta) + { + var metaOutputPath = Path.Combine(outputPath, ".meta"); + Log($"Adding {metaInputPath} to the transfer list."); + list.Add(new TransferFile(metaInputPath, metaOutputPath)); + } + else + { + Log("Meta file will be ignored"); + } + } + else + { + Log($"Found no meta file for {f}"); + } + }); + } + + Log($"Transfer list contains {list.Count} items"); + var success = 0; + var failed = 0; + var skipped = 0; + list.Do(f => + { + if (File.Exists(f.Output)) + { + if (Overwrite) + { + Log($"Output file {f.Output} already exists, it will be overwritten"); + if (f.IsMeta || Move) + { + Log($"Deleting file at {f.Output}"); + try + { + File.Delete(f.Output); + } + catch (Exception e) + { + Log($"Could not delete file {f.Output}!\n{e}"); + failed++; + } + } + } + else + { + Log($"Output file {f.Output} already exists, skipping"); + skipped++; + return; + } + } + + if (f.IsMeta) + { + Log($"Writing meta data to {f.Output}"); + try + { + File.WriteAllText(f.Output, f.Input, Encoding.UTF8); + success++; + } + catch (Exception e) + { + Log($"Error while writing meta data to {f.Output}!\n{e}"); + failed++; + } + } + else + { + if (Copy) + { + Log($"Copying file {f.Input} to {f.Output}"); + try + { + File.Copy(f.Input, f.Output, Overwrite); + success++; + } + catch (Exception e) + { + Log($"Error while copying file {f.Input} to {f.Output}!\n{e}"); + failed++; + } + } + else if(Move) + { + Log($"Moving file {f.Input} to {f.Output}"); + try + { + File.Move(f.Input, f.Output, Overwrite ? MoveOptions.ReplaceExisting : MoveOptions.None); + success++; + } + catch (Exception e) + { + Log($"Error while moving file {f.Input} to {f.Output}!\n{e}"); + failed++; + } + } + } + }); + + Log($"Skipped transfers: {skipped}"); + Log($"Failed transfers: {failed}"); + Log($"Successful transfers: {success}"); + + return 0; + } + } +} From d7becbfd1bc23b1b413803ebe74daa7d5d752faa Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 15:56:43 +0100 Subject: [PATCH 3/8] Added check to exit when both Copy and Move flags are set --- Wabbajack.CLI/Verbs/ChangeDownload.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Wabbajack.CLI/Verbs/ChangeDownload.cs b/Wabbajack.CLI/Verbs/ChangeDownload.cs index 59a82acf..122221de 100644 --- a/Wabbajack.CLI/Verbs/ChangeDownload.cs +++ b/Wabbajack.CLI/Verbs/ChangeDownload.cs @@ -86,6 +86,12 @@ namespace Wabbajack.CLI.Verbs return -1; } + if (Copy && Move) + { + Log("You can't set both copy and move flags!"); + return -1; + } + var isModlist = Modlist.EndsWith(Consts.ModListExtension); var list = new List(); From adf67c7ad910c14f33ae388f84392e19dca01da9 Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 16:24:50 +0100 Subject: [PATCH 4/8] Multiple small fixes --- Wabbajack.CLI/Verbs/ChangeDownload.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Wabbajack.CLI/Verbs/ChangeDownload.cs b/Wabbajack.CLI/Verbs/ChangeDownload.cs index 122221de..b3bec677 100644 --- a/Wabbajack.CLI/Verbs/ChangeDownload.cs +++ b/Wabbajack.CLI/Verbs/ChangeDownload.cs @@ -17,10 +17,10 @@ namespace Wabbajack.CLI.Verbs [Verb("change-download", HelpText = "Move or Copy all used Downloads from a Modlist to another directory")] public class ChangeDownload : AVerb { - [Option('i', "input", Required = true, HelpText = "Input folder containing the downloads you want to move")] + [Option("input", Required = true, HelpText = "Input folder containing the downloads you want to move")] public string Input { get; set; } - [Option('o', "output", Required = true, HelpText = "Output folder the downloads should be transferred to")] + [Option("output", Required = true, HelpText = "Output folder the downloads should be transferred to")] public string Output { get; set; } [Option("modlist", Required = true, HelpText = "The Modlist, can either be a .wabbajack or a modlist.txt file")] @@ -80,7 +80,7 @@ namespace Wabbajack.CLI.Verbs Directory.CreateDirectory(Output); } - if (!Modlist.EndsWith(Consts.ModListExtension) || !Modlist.EndsWith("modlist.txt")) + if (!Modlist.EndsWith(Consts.ModListExtension) && !Modlist.EndsWith("modlist.txt")) { Log($"The file {Modlist} is not a valid modlist file!"); return -1; @@ -171,7 +171,7 @@ namespace Wabbajack.CLI.Verbs } else { - if (Directory.Exists(Mods)) + if (!Directory.Exists(Mods)) { Log($"Mods directory {Mods} does not exist!"); return -1; @@ -313,7 +313,7 @@ namespace Wabbajack.CLI.Verbs Log($"Copying file {f.Input} to {f.Output}"); try { - File.Copy(f.Input, f.Output, Overwrite); + File.Copy(f.Input, f.Output, Overwrite ? CopyOptions.None : CopyOptions.FailIfExists, CopyMoveProgressHandler, null); success++; } catch (Exception e) @@ -327,7 +327,7 @@ namespace Wabbajack.CLI.Verbs Log($"Moving file {f.Input} to {f.Output}"); try { - File.Move(f.Input, f.Output, Overwrite ? MoveOptions.ReplaceExisting : MoveOptions.None); + File.Move(f.Input, f.Output, Overwrite ? MoveOptions.ReplaceExisting : MoveOptions.None, CopyMoveProgressHandler, null); success++; } catch (Exception e) @@ -345,5 +345,15 @@ namespace Wabbajack.CLI.Verbs return 0; } + + private static CopyMoveProgressResult CopyMoveProgressHandler(long totalfilesize, long totalbytestransferred, long streamsize, long streambytestransferred, int streamnumber, CopyMoveProgressCallbackReason callbackreason, object userdata) + { + Console.Write($"\r{' ', 100}"); + + Console.Write(totalfilesize == totalbytestransferred + ? "\rTransfer complete!\n" + : $"\rTotal Size: {totalfilesize}, Transferred: {totalbytestransferred}"); + return CopyMoveProgressResult.Continue; + } } } From e5539b5e2e4e519d4feaf0c407ab2ce5851b82b1 Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 16:43:42 +0100 Subject: [PATCH 5/8] Added non-functional sorting buttons --- Wabbajack/Views/ManifestView.xaml | 10 ++++++++++ Wabbajack/Views/ManifestView.xaml.cs | 3 --- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Wabbajack/Views/ManifestView.xaml b/Wabbajack/Views/ManifestView.xaml index 900cf364..a650488d 100644 --- a/Wabbajack/Views/ManifestView.xaml +++ b/Wabbajack/Views/ManifestView.xaml @@ -33,6 +33,16 @@ + + Order by: + + + + diff --git a/Wabbajack/Views/ManifestView.xaml.cs b/Wabbajack/Views/ManifestView.xaml.cs index c96b4de9..e997b68e 100644 --- a/Wabbajack/Views/ManifestView.xaml.cs +++ b/Wabbajack/Views/ManifestView.xaml.cs @@ -5,11 +5,8 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Media; using System.Windows.Navigation; -using System.Windows.Shapes; using ReactiveUI; -using Wabbajack.Common; using Wabbajack.Lib; namespace Wabbajack From ea39485f27508f07461f6a09c1f1219f3c29bf6d Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 17:10:02 +0100 Subject: [PATCH 6/8] Add sort functions to the new buttons --- Wabbajack/View Models/ManifestVM.cs | 69 ++++++++++++++++++++++++++-- Wabbajack/Views/ManifestView.xaml.cs | 4 ++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/Wabbajack/View Models/ManifestVM.cs b/Wabbajack/View Models/ManifestVM.cs index 19293e04..d502903b 100644 --- a/Wabbajack/View Models/ManifestVM.cs +++ b/Wabbajack/View Models/ManifestVM.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reactive; using System.Reactive.Linq; +using CefSharp; using ReactiveUI; using ReactiveUI.Fody.Helpers; using Wabbajack.Common; @@ -9,8 +11,10 @@ using Wabbajack.Lib; namespace Wabbajack { + public enum SortBy { Name, Size } + public class ManifestVM : ViewModel - { + { public Manifest Manifest { get; set; } public string Name => !string.IsNullOrWhiteSpace(Manifest.Name) ? Manifest.Name : "Wabbajack Modlist"; @@ -27,28 +31,83 @@ namespace Wabbajack private readonly ObservableAsPropertyHelper> _searchResults; public IEnumerable SearchResults => _searchResults.Value; + [Reactive] + public bool SortAscending { get; set; } = true; + + [Reactive] + public SortBy SortEnum { get; set; } = SortBy.Name; + + public ReactiveCommand SortByNameCommand; + public ReactiveCommand SortBySizeCommand; + + private IEnumerable Order(IEnumerable list) + { + if (SortAscending) + { + return list.OrderBy(x => + { + return SortEnum switch + { + SortBy.Name => x.Name, + SortBy.Size => x.Name, + _ => throw new ArgumentOutOfRangeException() + }; + }); + } + + return list.OrderByDescending(x => + { + return SortEnum switch + { + SortBy.Name => x.Name, + SortBy.Size => x.Name, + _ => throw new ArgumentOutOfRangeException() + }; + }); + } + public ManifestVM(Manifest manifest) { Manifest = manifest; + SortByNameCommand = ReactiveCommand.Create(() => + { + if (SortEnum != SortBy.Name) + SortEnum = SortBy.Name; + else + SortAscending = !SortAscending; + }); + + SortBySizeCommand = ReactiveCommand.Create(() => + { + if (SortEnum != SortBy.Size) + SortEnum = SortBy.Size; + else + SortAscending = !SortAscending; + }); + _searchResults = this.WhenAnyValue(x => x.SearchTerm) + /*.CombineLatest( + this.WhenAnyValue(x => x.SortAscending), + this.WhenAnyValue(x => x.SortEnum), + (term, ascending, sort) => term)*/ .Throttle(TimeSpan.FromMilliseconds(800)) .Select(term => term?.Trim()) .DistinctUntilChanged() .Select(term => { if (string.IsNullOrWhiteSpace(term)) - return Archives; + return Order(Archives); - return Archives.Where(x => + return Order(Archives.Where(x => { if (term.StartsWith("hash:")) return x.Hash.StartsWith(term.Replace("hash:", "")); return x.Name.StartsWith(term); - }); + })); }) - .ToGuiProperty(this, nameof(SearchResults), Archives); + .ToGuiProperty(this, nameof(SearchResults), Order(Archives)); } } } diff --git a/Wabbajack/Views/ManifestView.xaml.cs b/Wabbajack/Views/ManifestView.xaml.cs index e997b68e..f7775036 100644 --- a/Wabbajack/Views/ManifestView.xaml.cs +++ b/Wabbajack/Views/ManifestView.xaml.cs @@ -41,6 +41,10 @@ namespace Wabbajack .DisposeWith(disposable); this.Bind(ViewModel, x => x.SearchTerm, x => x.SearchBar.Text) .DisposeWith(disposable); + this.BindCommand(ViewModel, x => x.SortByNameCommand, x => x.OrderByNameButton) + .DisposeWith(disposable); + this.BindCommand(ViewModel, x => x.SortBySizeCommand, x => x.OrderBySizeButton) + .DisposeWith(disposable); }); } From e764e59ff6582e03cb24523b997af70dfbd4c682 Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 17:35:34 +0100 Subject: [PATCH 7/8] Sorting buttons now update the result --- Wabbajack/View Models/ManifestVM.cs | 39 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Wabbajack/View Models/ManifestVM.cs b/Wabbajack/View Models/ManifestVM.cs index d502903b..c047e388 100644 --- a/Wabbajack/View Models/ManifestVM.cs +++ b/Wabbajack/View Models/ManifestVM.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reactive; using System.Reactive.Linq; using CefSharp; +using DynamicData.Binding; using ReactiveUI; using ReactiveUI.Fody.Helpers; using Wabbajack.Common; @@ -43,27 +44,21 @@ namespace Wabbajack private IEnumerable Order(IEnumerable list) { if (SortAscending) - { - return list.OrderBy(x => - { - return SortEnum switch - { - SortBy.Name => x.Name, - SortBy.Size => x.Name, - _ => throw new ArgumentOutOfRangeException() - }; - }); - } - - return list.OrderByDescending(x => { return SortEnum switch { - SortBy.Name => x.Name, - SortBy.Size => x.Name, + SortBy.Name => list.OrderBy(x => x.Name), + SortBy.Size => list.OrderBy(x => x.Size), _ => throw new ArgumentOutOfRangeException() }; - }); + } + + return SortEnum switch + { + SortBy.Name => list.OrderByDescending(x => x.Name), + SortBy.Size => list.OrderByDescending(x => x.Size), + _ => throw new ArgumentOutOfRangeException() + }; } public ManifestVM(Manifest manifest) @@ -73,7 +68,10 @@ namespace Wabbajack SortByNameCommand = ReactiveCommand.Create(() => { if (SortEnum != SortBy.Name) + { SortEnum = SortBy.Name; + SortAscending = true; + } else SortAscending = !SortAscending; }); @@ -81,20 +79,23 @@ namespace Wabbajack SortBySizeCommand = ReactiveCommand.Create(() => { if (SortEnum != SortBy.Size) + { SortEnum = SortBy.Size; + SortAscending = true; + } else SortAscending = !SortAscending; }); _searchResults = this.WhenAnyValue(x => x.SearchTerm) - /*.CombineLatest( + .CombineLatest( this.WhenAnyValue(x => x.SortAscending), this.WhenAnyValue(x => x.SortEnum), - (term, ascending, sort) => term)*/ + (term, ascending, sort) => term) .Throttle(TimeSpan.FromMilliseconds(800)) .Select(term => term?.Trim()) - .DistinctUntilChanged() + //.DistinctUntilChanged() .Select(term => { if (string.IsNullOrWhiteSpace(term)) From 6c31beeaf5c5dc18b7e43522a911d7c93efd1c74 Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 19 Feb 2020 17:37:03 +0100 Subject: [PATCH 8/8] Simplified the ReactiveCommand --- Wabbajack/View Models/ManifestVM.cs | 32 +++++++++-------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/Wabbajack/View Models/ManifestVM.cs b/Wabbajack/View Models/ManifestVM.cs index c047e388..8287e81f 100644 --- a/Wabbajack/View Models/ManifestVM.cs +++ b/Wabbajack/View Models/ManifestVM.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Reactive; using System.Reactive.Linq; -using CefSharp; -using DynamicData.Binding; using ReactiveUI; using ReactiveUI.Fody.Helpers; using Wabbajack.Common; @@ -61,31 +59,21 @@ namespace Wabbajack }; } + private void Swap(SortBy to) + { + if (SortEnum != to) + SortEnum = to; + else + SortAscending = !SortAscending; + } + public ManifestVM(Manifest manifest) { Manifest = manifest; - SortByNameCommand = ReactiveCommand.Create(() => - { - if (SortEnum != SortBy.Name) - { - SortEnum = SortBy.Name; - SortAscending = true; - } - else - SortAscending = !SortAscending; - }); + SortByNameCommand = ReactiveCommand.Create(() => Swap(SortBy.Name)); - SortBySizeCommand = ReactiveCommand.Create(() => - { - if (SortEnum != SortBy.Size) - { - SortEnum = SortBy.Size; - SortAscending = true; - } - else - SortAscending = !SortAscending; - }); + SortBySizeCommand = ReactiveCommand.Create(() => Swap(SortBy.Size)); _searchResults = this.WhenAnyValue(x => x.SearchTerm)