Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional UI changes to help user confusion and information #2374

Closed
wants to merge 9 commits into from
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
### Changelog

### Version - TBA
* Fixed some UI issues arising from 3.2.0.0 changes - more informative error text, drive space checking, wiki link button

#### Version - 3.2.0.1 - 7/23/2023
* Code cleanup: re-added some network and diagnostic code missing since 2.5

Expand Down
79 changes: 61 additions & 18 deletions Wabbajack.App.Wpf/View Models/Installers/InstallerVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,14 @@ public class InstallerVM : BackNavigatingVM, IBackNavigatingVM, ICpuStatusVM
public LogStream LoggerProvider { get; }

private AbsolutePath LastInstallPath { get; set; }

[Reactive] public bool OverwriteFiles { get; set; }


// Command properties
public ReactiveCommand<Unit, Unit> ShowManifestCommand { get; }
public ReactiveCommand<Unit, Unit> OpenReadmeCommand { get; }
public ReactiveCommand<Unit, Unit> OpenWikiCommand { get; }
public ReactiveCommand<Unit, Unit> OpenDiscordButton { get; }
public ReactiveCommand<Unit, Unit> VisitModListWebsiteCommand { get; }

Expand Down Expand Up @@ -178,6 +181,11 @@ public InstallerVM(ILogger<InstallerVM> 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);
Expand Down Expand Up @@ -219,7 +227,10 @@ public InstallerVM(ILogger<InstallerVM> logger, DTOSerializer dtos, SettingsMana
{
UIUtils.OpenFolder(Installer.Location.TargetPath);
});


this.WhenAnyValue(x => x.OverwriteFiles)
.Subscribe(x => ConfirmOverwrite());

MessageBus.Current.Listen<LoadModlistForInstalling>()
.Subscribe(msg => LoadModlistFromGallery(msg.Path, msg.Metadata).FireAndForget())
.DisposeWith(CompositeDisposable);
Expand Down Expand Up @@ -280,6 +291,10 @@ private IEnumerable<ErrorResponse> 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))
Expand All @@ -304,31 +319,52 @@ private IEnumerable<ErrorResponse> Validate()
yield return ErrorResponse.Fail("Installing in this folder may overwrite Wabbajack");
}

if (installPath.ToString().Length != 0 && installPath != LastInstallPath &&
!Installer.AutomaticallyOverwrite &&
if (installPath.ToString().Length != 0 && installPath != LastInstallPath && !OverwriteFiles &&
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?";
string title = "Files found in install folder";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result = MessageBox.Show(message, title, buttons);
if (result == DialogResult.Yes)
{
// everythings fine
}
else
{
Installer.Location.TargetPath = "".ToAbsolutePath();
}
yield return ErrorResponse.Fail("There are files in the install folder, please tick 'Overwrite Installation' to confirm you want to install to this folder " + Environment.NewLine +
"if you are updating an existing modlist, then this is expected and can be overwritten.");
}

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 into Windows locations such as Documents etc, please make a new folder for the modlist - C:\\ModList\\ for example.");
}

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)
Expand Down Expand Up @@ -411,6 +447,13 @@ private async Task LoadModlist(AbsolutePath path, ModlistMetadata? metadata)
}
}

private void ConfirmOverwrite()
{
AbsolutePath prev = Installer.Location.TargetPath;
Installer.Location.TargetPath = "".ToAbsolutePath();
Installer.Location.TargetPath = prev;
}

private async Task BeginInstall()
{
await Task.Run(async () =>
Expand Down Expand Up @@ -551,4 +594,4 @@ private async Task PopulateNextModSlide(ModList modList)
}
}

}
}
30 changes: 27 additions & 3 deletions Wabbajack.App.Wpf/Views/Installers/InstallationCompleteView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
x:TypeArguments="local:InstallerVM"
mc:Ignorable="d">
<local:AttentionBorder x:Name="AttentionBorder" ClipToBounds="True">
<Grid Margin="5">
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="3*" />
Expand All @@ -23,6 +23,7 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="5"
x:Name="TitleText"
Expand Down Expand Up @@ -124,11 +125,34 @@
<TextBlock Grid.Row="1"
Margin="0,10,0,0"
HorizontalAlignment="Center"
Text="Readme" />
Text="Modlist Readme" />
</Grid>
<Grid Grid.Row="1" Grid.Column="4"
VerticalAlignment="Center"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button
x:Name="OpenWikiButton"
Width="50"
Height="50"
Style="{StaticResource CircleButtonStyle}">
<icon:PackIconFontAwesome
Width="25"
Height="25"
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
Kind="QuestionSolid" />
</Button>
<TextBlock Grid.Row="1"
Margin="0,10,0,0"
HorizontalAlignment="Center"
Text="Help and Wiki" />
</Grid>
<Grid Grid.Row="1" Grid.Column="5"
VerticalAlignment="Center"
Background="Transparent">
Background="Transparent" Grid.ColumnSpan="2" Margin="0,0,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
FontSize="14"
Text="Target Modlist"
TextAlignment="Center" />
<TextBlock x:Name="errorTextBox"
Grid.Row="3"
FontFamily="Verdana" FontSize="10" FontWeight="ExtraBold"
Background="{StaticResource WindowBackgroundBrush}"
Foreground="Red"
Text=""
TextAlignment="Left" Margin="0,79,0,-45" Grid.ColumnSpan="3" />
<local:FilePicker Grid.Row="1" Grid.Column="2"
x:Name="ModListLocationPicker"
Height="30"
Expand Down Expand Up @@ -74,10 +81,11 @@
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:BeginButton Grid.Row="1"
x:Name="BeginButton"
HorizontalAlignment="Right"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<icon:PackIconFontAwesome Grid.Row="2"
x:Name="ErrorSummaryIconGlow"
Expand All @@ -92,8 +100,27 @@
<icon:PackIconFontAwesome Grid.Row="2"
x:Name="ErrorSummaryIcon"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Foreground="{StaticResource WarningBrush}"
Kind="ExclamationTriangleSolid" />
<CheckBox Grid.Row="2" Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
x:Name="OverwriteCheckBox"
Content="Overwrite Installation"
IsChecked="False"
ToolTip="Confirm to overwrite files in install folder.">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Opacity" Value="0.6" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Opacity" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</Grid>
</Grid>
</rxui:ReactiveUserControl>
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,21 @@ public InstallationConfigurationView()
this.WhenAny(x => x.ViewModel.BeginCommand)
.BindToStrict(this, x => x.BeginButton.Command)
.DisposeWith(dispose);

this.BindStrict(ViewModel, vm => vm.OverwriteFiles, x => x.OverwriteCheckBox.IsChecked)
.DisposeWith(dispose);

// Error handling

this.WhenAnyValue(x => x.ViewModel.ErrorState)
.Select(v => !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)
Expand Down
16 changes: 0 additions & 16 deletions Wabbajack.App.Wpf/Views/Installers/MO2InstallerConfigView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,5 @@
FontSize="14"
PickerVM="{Binding DownloadLocation}"
ToolTip="The directory where modlist archives will be downloaded to" />
<CheckBox Grid.Row="2" Grid.Column="2"
HorizontalAlignment="Right"
Content="Overwrite Installation"
IsChecked="{Binding AutomaticallyOverwrite}"
ToolTip="If installing over an existing installation, automatically replace it without asking permission.">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Opacity" Value="0.6" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Opacity" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
x:Name="ExtendedDescription"
TextWrapping="WrapWithOverflow" />
<CheckBox Grid.Row="2" Grid.Column="2"
x:Name="AutoOverwriteCheckbox"
Margin="4"
HorizontalAlignment="Right"
Content="Remember"
IsChecked="{Binding Installer.AutomaticallyOverwrite}"
ToolTip="If installing over an existing installation next time, automatically replace it without asking permission." />
<Button Grid.Row="3" Grid.Column="0"
x:Name="CancelButton"
Content="Cancel" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ public ConfirmUpdateOfExistingInstallView()
this.WhenAny(x => x.ViewModel.Source.CancelCommand)
.BindToStrict(this, x => x.CancelButton.Command)
.DisposeWith(dispose);

this.BindStrict(this.ViewModel, x => x.Installer.AutomaticallyOverwrite, x => x.AutoOverwriteCheckbox.IsChecked,
vmToViewConverter: x => x,
viewToVmConverter: x => x ?? false)
.DisposeWith(dispose);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion Wabbajack.Launcher/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ private async Task VerifyCurrentLocation()
ShowInCenter = true,
ContentTitle = "Wabbajack Launcher: Bad startup path",
ContentMessage =
"Cannot start in the root of a drive, or protected folder locations such as Downloads, Desktop etc.\nPlease move Wabbajack to another folder."
"Cannot start in the root of a drive, or protected folder locations such as Downloads, Desktop etc.\nPlease move Wabbajack to another folder, creating a new folder if necessary ( example : C:\\Wabbajack\\), outside of these locations."
});
var result = await msg.Show();
Environment.Exit(1);
Expand Down