From 98c12d46f0822872e9e1b44e2fb6c45f396a15aa Mon Sep 17 00:00:00 2001 From: JanuarySnow Date: Wed, 19 Jul 2023 20:08:08 +0100 Subject: [PATCH 1/8] 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 c5198d133..d09683fe0 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.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 InstallerVM(ILogger logger, DTOSerializer dtos, SettingsMana 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 @@ private IEnumerable Validate() { 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 @@ private IEnumerable Validate() } 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 @@ private IEnumerable Validate() 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 8e87a272d..c4f2e93d1 100644 --- a/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs +++ b/Wabbajack.App.Wpf/View Models/Installers/MO2InstallerVM.cs @@ -39,9 +39,6 @@ public class MO2InstallerVM : ViewModel, ISubInstallerVM public bool SupportsAfterInstallNavigation => true; - [Reactive] - public bool AutomaticallyOverwrite { get; set; } - public int ConfigVisualVerticalOffset => 25; public MO2InstallerVM(InstallerVM installerVM) @@ -166,7 +163,6 @@ private void SaveSettings(Mo2ModlistInstallationSettings settings) 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 74284763b..f76f9d150 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 d2e70061b..b4000b86d 100644 --- a/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs +++ b/Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml.cs @@ -46,6 +46,9 @@ public InstallationCompleteView() 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 225346f0d..5cd461c9c 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 5561d7fd3..f47095f33 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 60620f632..de4ff6b92 100644 --- a/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml +++ b/Wabbajack.App.Wpf/Views/Interventions/ConfirmUpdateOfExistingInstallView.xaml @@ -33,13 +33,6 @@ -