From 98c12d46f0822872e9e1b44e2fb6c45f396a15aa Mon Sep 17 00:00:00 2001 From: JanuarySnow Date: Wed, 19 Jul 2023 20:08:08 +0100 Subject: [PATCH 1/2] added more visible error messages to avoid user confusion added hard drive free space detection, added red error message text, removed overwrite checkbox, added wiki button link extended the error text for starting wabbajack in protected location removed debug code shortened error message to fit in text box --- .../View Models/Installers/InstallerVM.cs | 52 +++++++++++++++++-- .../View Models/Installers/MO2InstallerVM.cs | 4 -- .../Installers/InstallationCompleteView.xaml | 30 +++++++++-- .../InstallationCompleteView.xaml.cs | 3 ++ .../InstallationConfigurationView.xaml | 7 +++ .../InstallationConfigurationView.xaml.cs | 7 ++- .../Installers/MO2InstallerConfigView.xaml | 16 ------ .../ConfirmUpdateOfExistingInstallView.xaml | 7 --- ...ConfirmUpdateOfExistingInstallView.xaml.cs | 5 -- .../ViewModels/MainWindowViewModel.cs | 3 +- 10 files changed, 93 insertions(+), 41 deletions(-) diff --git a/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs b/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs index c5198d13..d09683fe 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs @@ -35,6 +35,8 @@ using Wabbajack.Paths.IO; using Wabbajack.Services.OSIntegrated; using Wabbajack.Util; using System.Windows.Forms; +using System.Web; +using System.Diagnostics; namespace Wabbajack; @@ -140,6 +142,7 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM // Command properties public ReactiveCommand ShowManifestCommand { get; } public ReactiveCommand OpenReadmeCommand { get; } + public ReactiveCommand OpenWikiCommand { get; } public ReactiveCommand OpenDiscordButton { get; } public ReactiveCommand VisitModListWebsiteCommand { get; } @@ -178,6 +181,11 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM UIUtils.OpenWebsite(new Uri(ModList!.Readme)); }, this.WhenAnyValue(vm => vm.LoadingLock.IsNotLoading, vm => vm.ModList.Readme, (isNotLoading, readme) => isNotLoading && !string.IsNullOrWhiteSpace(readme))); + OpenWikiCommand = ReactiveCommand.Create(() => + { + UIUtils.OpenWebsite(new Uri("https://wiki.wabbajack.org/index.html")); + }, this.WhenAnyValue(vm => vm.LoadingLock.IsNotLoading)); + VisitModListWebsiteCommand = ReactiveCommand.Create(() => { UIUtils.OpenWebsite(ModList!.Website); @@ -280,6 +288,10 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM { yield return ErrorResponse.Fail("Can't have identical install and download folders"); } + if (installPath.ToString().Length > 0 && downloadPath.ToString().Length > 0 && KnownFolders.IsSubDirectoryOf(installPath.ToString(), downloadPath.ToString())) + { + yield return ErrorResponse.Fail("Can't put the install folder inside the download folder"); + } foreach (var game in GameRegistry.Games) { if (!_gameLocator.TryFindLocation(game.Key, out var location)) @@ -305,11 +317,12 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM } if (installPath.ToString().Length != 0 && installPath != LastInstallPath && - !Installer.AutomaticallyOverwrite && Directory.EnumerateFileSystemEntries(installPath.ToString()).Any()) { string message = - "There are existing files in the chosen install path, they will be deleted or overwritten (if updating existing modlist), continue?"; + "There are files already in the chosen install path, if you are updating an existing modlist, this is fine. " + Environment.NewLine + + " Otherwise, please ensure you intend for the folder contents to be deleted during the modlist install." + Environment.NewLine + + " Continue? "; string title = "Files found in install folder"; MessageBoxButtons buttons = MessageBoxButtons.YesNo; DialogResult result = MessageBox.Show(message, title, buttons); @@ -325,10 +338,43 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM if (KnownFolders.IsInSpecialFolder(installPath) || KnownFolders.IsInSpecialFolder(downloadPath)) { - yield return ErrorResponse.Fail("Can't install a modlist into Windows protected locations - such as Downloads, Documents etc"); + yield return ErrorResponse.Fail("Can't install a modlist into Windows protected locations - such as Downloads,Documents etc, please make a new folder for the modlist."); + } + + if (installPath.ToString().Length > 0 && downloadPath.ToString().Length > 0 && !HasEnoughSpace(installPath, downloadPath)){ + yield return ErrorResponse.Fail("Can't install modlist due to lack of free hard drive space, please read the modlist Readme to learn more."); } } + private bool HasEnoughSpace(AbsolutePath inpath, AbsolutePath downpath) + { + string driveLetterInPath = inpath.ToString().Substring(0,1); + string driveLetterDownPath = inpath.ToString().Substring(0,1); + DriveInfo driveUsedInPath = new DriveInfo(driveLetterInPath); + DriveInfo driveUsedDownPath = new DriveInfo(driveLetterDownPath); + long spaceRequiredforInstall = ModlistMetadata.DownloadMetadata.SizeOfInstalledFiles; + long spaceRequiredforDownload = ModlistMetadata.DownloadMetadata.SizeOfArchives; + long spaceInstRemaining = driveUsedInPath.AvailableFreeSpace; + long spaceDownRemaining = driveUsedDownPath.AvailableFreeSpace; + if ( driveLetterInPath == driveLetterDownPath) + { + long totalSpaceRequired = spaceRequiredforInstall + spaceRequiredforDownload; + if (spaceInstRemaining < totalSpaceRequired) + { + return false; + } + + } else + { + if( spaceInstRemaining < spaceRequiredforInstall || spaceDownRemaining < spaceRequiredforDownload) + { + return false; + } + } + return true; + + } + private async Task BeginSlideShow(CancellationToken token) { while (!token.IsCancellationRequested) diff --git a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs index 8e87a272..c4f2e93d 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs @@ -39,9 +39,6 @@ namespace Wabbajack public bool SupportsAfterInstallNavigation => true; - [Reactive] - public bool AutomaticallyOverwrite { get; set; } - public int ConfigVisualVerticalOffset => 25; public MO2InstallerVM(InstallerVM installerVM) @@ -166,7 +163,6 @@ namespace Wabbajack if (settings == null) return; settings.InstallationLocation = Location.TargetPath; settings.DownloadLocation = DownloadLocation.TargetPath; - settings.AutomaticallyOverrideExistingInstall = AutomaticallyOverwrite; } public void AfterInstallNavigation() diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml index 74284763..f76f9d15 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml @@ -12,7 +12,7 @@ x:TypeArguments="local:InstallerVM" mc:Ignorable="d"> - + @@ -23,6 +23,7 @@ + + Text="Modlist Readme" /> + + + + + + + + + Background="Transparent" Grid.ColumnSpan="2" Margin="0,0,10,0"> diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs index d2e70061..b4000b86 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs @@ -46,6 +46,9 @@ namespace Wabbajack this.WhenAny(x => x.ViewModel.OpenReadmeCommand) .BindToStrict(this, x => x.OpenReadmeButton.Command) .DisposeWith(dispose); + this.WhenAny(x => x.ViewModel.OpenWikiCommand) + .BindToStrict(this, x => x.OpenWikiButton.Command) + .DisposeWith(dispose); this.WhenAny(x => x.ViewModel.CloseWhenCompleteCommand) .BindToStrict(this, x => x.CloseButton.Command) .DisposeWith(dispose); diff --git a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml index 225346f0..5cd461c9 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationConfigurationView.xaml @@ -39,6 +39,13 @@ FontSize="14" Text="Target Modlist" TextAlignment="Center" /> + !v.Failed) .BindToStrict(this, view => view.BeginButton.IsEnabled) .DisposeWith(dispose); - + + this.WhenAnyValue(x => x.ViewModel.ErrorState) + .Select(v => v.Reason) + .BindToStrict(this, view => view.errorTextBox.Text) + .DisposeWith(dispose); + this.WhenAnyValue(x => x.ViewModel.ErrorState) .Select(v => v.Failed ? Visibility.Visible : Visibility.Hidden) .BindToStrict(this, view => view.ErrorSummaryIcon.Visibility) diff --git a/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml b/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml index 5561d7fd..f47095f3 100644 --- a/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml +++ b/Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml @@ -46,21 +46,5 @@ FontSize="14" PickerVM="{Binding DownloadLocation}" ToolTip="The directory where modlist archives will be downloaded to" /> - - - - - diff --git a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml b/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml index 60620f63..de4ff6b9 100644 --- a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml +++ b/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml @@ -33,13 +33,6 @@ -