Skip to content
This repository has been archived by the owner on Jul 28, 2021. It is now read-only.

Commit

Permalink
Install, update and remove multiple mods in one go
Browse files Browse the repository at this point in the history
  • Loading branch information
nrgill28 committed Apr 10, 2021
1 parent 93d1ca7 commit 6dceccf
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 40 deletions.
24 changes: 22 additions & 2 deletions DeliCounter/Backend/ModManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,26 @@ internal static class ModManagement
internal static void InstallMod(Mod mod, Version versionNumber)
{
App.RunInBackgroundThread(() => { ExecuteOperations(EnumerateInstallDependencies(mod, versionNumber).Concat(new[] { new InstallModOperation(mod, versionNumber) })); });
}

internal static void InstallMods(IEnumerable<Mod> mods)
{
App.RunInBackgroundThread(() => {
IEnumerable<ModOperation.ModOperation> enumerable = Array.Empty<ModOperation.ModOperation>();
foreach (Mod mod in mods)
enumerable = enumerable.Concat(EnumerateInstallDependencies(mod, mod.LatestVersion).Concat(new[] { new InstallModOperation(mod, mod.LatestVersion) }));
ExecuteOperations(enumerable);
});
}

internal static void UninstallMod(Mod mod)
internal static void UninstallMods(IEnumerable<Mod> mods)
{
App.RunInBackgroundThread(() => { ExecuteOperations(EnumerateUninstallDependencies(mod).Concat(new[] { new UninstallModOperation(mod) })); });
App.RunInBackgroundThread(() => {
IEnumerable <ModOperation.ModOperation> enumerable = Array.Empty<ModOperation.ModOperation>();
foreach (Mod mod in mods)
enumerable = enumerable.Concat(EnumerateUninstallDependencies(mod).Concat(new[] { new UninstallModOperation(mod) }));
ExecuteOperations(enumerable);
});
}

internal static void UpdateMod(Mod mod, Version versionNumber)
Expand Down Expand Up @@ -61,6 +76,11 @@ internal static void UpdateMod(Mod mod, Version versionNumber)
dialogue.ShowAsync();
});
});
}

internal static void UpdateMods(IEnumerable<Mod> mods)
{
foreach (Mod mod in mods) UpdateMod(mod, mod.LatestVersion);
}

internal static void DefaultAction(Mod mod)
Expand Down
2 changes: 1 addition & 1 deletion DeliCounter/Backend/ModRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void Refresh()
LoadModCache();
Exception = updateResult;
RepositoryUpdated?.Invoke();
App.RunInMainThread(() => MainWindow.Instance.ModManagementDrawer.SetMod(null));
App.RunInMainThread(MainWindow.Instance.ModManagementDrawer.ClearSelected);
}

/// <summary>
Expand Down
138 changes: 108 additions & 30 deletions DeliCounter/Controls/ModManagementDrawer.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using DeliCounter.Backend;
using ModernWpf.Controls;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
Expand All @@ -16,7 +18,7 @@ namespace DeliCounter.Controls
/// </summary>
public partial class ModManagementDrawer : UserControl
{
private Mod _selectedMod;
private List<Mod> _selectedMods = new();
private Version _selectedVersion;

public ModManagementDrawer()
Expand All @@ -25,30 +27,62 @@ public ModManagementDrawer()
UpdateDisplay();
}

public void SetMod(Mod mod)
public void ClearSelected()
{
_selectedMod = mod;
if (mod is not null)
_selectedMods.Clear();
SelectedUpdated();
}

public void AddSelected(IList selected)
{
foreach (ModListItem item in selected)
_selectedMods.Add(item.Mod);
}

public void RemoveSelected(IList selected)
{
foreach (ModListItem item in selected)
_selectedMods.Remove(item.Mod);
}

public void SelectedUpdated()
{
if (_selectedMods.Count == 1)
{
_selectedVersion = mod.InstalledVersion ?? mod.LatestVersion;
ComboBoxVersion.IsEnabled = _selectedMod.Versions.Count > 1;
ComboBoxVersion.Visibility = Visibility.Visible;
ComboBoxVersion.ItemsSource = _selectedMod.Versions.Keys.OrderByDescending(x => x);
_selectedVersion = _selectedMod.Versions.Keys.Max();
ComboBoxVersion.SelectedItem = _selectedVersion;
Mod mod = _selectedMods[0];
if (mod is not null)
{
_selectedVersion = mod.InstalledVersion ?? mod.LatestVersion;
ComboBoxVersion.IsEnabled = mod.Versions.Count > 1;
ComboBoxVersion.Visibility = Visibility.Visible;
ComboBoxVersion.ItemsSource = mod.Versions.Keys.OrderByDescending(x => x);
_selectedVersion = mod.Versions.Keys.Max();
ComboBoxVersion.SelectedItem = _selectedVersion;
}
}

UpdateDisplay();
}

public void UpdateDisplay()
{
if (_selectedMod == null)
if (_selectedMods.Count == 0)
{
UpdateShowNone();
return;
} else if (_selectedMods.Count > 1)
{
UpdateShowMany();
return;
}

Mod.ModVersion version = _selectedMod.Versions[_selectedVersion ?? _selectedMod.LatestVersion];
Mod mod = _selectedMods[0];
Mod.ModVersion version = mod.Versions[_selectedVersion ?? mod.LatestVersion];

// Reset the button contents
ButtonInstall.Content = "Install";
ButtonUpdate.Content = "Update";
ButtonUninstall.Content = "Uninstall";

// Update text block visibility
TextBlockDescriptionWrapper.Visibility = Visibility.Visible;
Expand All @@ -62,21 +96,21 @@ public void UpdateDisplay()
TextBlockTitle.Text = version.Name;
TextBlockDescription.Text = version.Description;
TextBlockAuthors.Text = string.Join(", ", version.Authors);
TextBlockLatest.Text = _selectedMod.LatestVersion.ToString();
TextBlockInstalled.Text = _selectedMod.IsInstalled ? _selectedMod.Installed?.VersionNumber?.ToString() ?? "0.0.0" : "No";
TextBlockLatest.Text = mod.LatestVersion.ToString();
TextBlockInstalled.Text = mod.IsInstalled ? mod.Installed?.VersionNumber?.ToString() ?? "0.0.0" : "No";
TextBlockDependencies.Text = string.Join(", ", version.Dependencies.Select(x => x.Key + " " + x.Value));
TextBlockSource.Text = version.SourceUrl;
HyperlinkSource.NavigateUri = !string.IsNullOrEmpty(version.SourceUrl) ? new Uri(version.SourceUrl, UriKind.Absolute) : null;

// Update the action button visibility
if (_selectedMod.IsInstalled)
if (mod.IsInstalled)
{
ButtonInstall.IsEnabled = false;
ButtonInstall.Visibility = Visibility.Collapsed;
ButtonUninstall.IsEnabled = true;
ButtonUninstall.Visibility = Visibility.Visible;
ButtonUpdate.IsEnabled = !_selectedMod.UpToDate;
ButtonUpdate.Visibility = _selectedMod.UpToDate ? Visibility.Collapsed : Visibility.Visible;
ButtonUpdate.IsEnabled = !mod.UpToDate;
ButtonUpdate.Visibility = mod.UpToDate ? Visibility.Collapsed : Visibility.Visible;
}
else
{
Expand Down Expand Up @@ -125,7 +159,46 @@ private void UpdateShowNone()

// Combobox
ComboBoxVersion.IsEnabled = false;
ComboBoxVersion.Visibility = Visibility.Collapsed;
ComboBoxVersion.Visibility = Visibility.Collapsed;
ComboBoxVersion.ItemsSource = null;

// Preview Image
ModPreviewImage.Visibility = Visibility.Collapsed;
}

private void UpdateShowMany()
{
// Hide all the text blocks
TextBlockTitle.Text = $"{_selectedMods.Count} mods selected";
TextBlockDescriptionWrapper.Visibility = Visibility.Collapsed;
TextBlockLatestWrapper.Visibility = Visibility.Collapsed;
TextBlockInstalledWrapper.Visibility = Visibility.Collapsed;
TextBlockAuthorsWrapper.Visibility = Visibility.Collapsed;
TextBlockDependenciesWrapper.Visibility = Visibility.Collapsed;
TextBlockSourceWrapper.Visibility = Visibility.Collapsed;

// Counts
int installable = _selectedMods.Count(x => !x.IsInstalled);
int updatable = _selectedMods.Count(x => !x.UpToDate && x.IsInstalled);
int removable = _selectedMods.Count(x => x.IsInstalled);

// Button text
ButtonInstall.Content = $"Install {installable}";
ButtonUpdate.Content = $"Update {updatable}";
ButtonUninstall.Content = $"Uninstall {removable}";

// Enable and make the buttons visible
ButtonInstall.IsEnabled = installable > 0;
ButtonInstall.Visibility = installable > 0 ? Visibility.Visible : Visibility.Collapsed;
ButtonUpdate.IsEnabled = updatable > 0;
ButtonUpdate.Visibility = updatable > 0 ? Visibility.Visible : Visibility.Collapsed;
ButtonUninstall.IsEnabled = removable > 0;
ButtonUninstall.Visibility = removable > 0 ? Visibility.Visible : Visibility.Collapsed;

// Combobox
ComboBoxVersion.IsEnabled = false;
ComboBoxVersion.Visibility = Visibility.Collapsed;
ComboBoxVersion.ItemsSource = null;

// Preview Image
ModPreviewImage.Visibility = Visibility.Collapsed;
Expand All @@ -142,19 +215,20 @@ private void HyperlinkSource_OnRequestNavigate(object sender, RequestNavigateEve
}

private void ButtonInstall_Click(object sender, RoutedEventArgs e)
{
ModManagement.InstallMod(_selectedMod, _selectedVersion);
{
if (_selectedMods.Count == 1)
ModManagement.InstallMod(_selectedMods[0], _selectedVersion);
else
ModManagement.InstallMods(_selectedMods);
}

private async void ButtonUninstall_Click(object sender, RoutedEventArgs e)
{
var mod = _selectedMod;

var dependentCount = mod.InstalledDependents.Count();
{
int dependentCount = _selectedMods.SelectMany(x => x.InstalledDependents).Distinct().Count();
if (dependentCount > 0)
{
// Confirm they want to do this
var alert = new AlertDialogue("Are you sure?", $"You have {dependentCount} mod(s) installed which directly depend on this one, they will also be uninstalled. This operation is cascading.")
var alert = new AlertDialogue("Are you sure?", $"Removing the selected mods will also remove their dependencies! This will uninstall {dependentCount + 1} mods.")
{
DefaultButton = ContentDialogButton.Primary,
PrimaryButtonText = "Ok",
Expand All @@ -165,12 +239,15 @@ private async void ButtonUninstall_Click(object sender, RoutedEventArgs e)
}

// Uninstall
ModManagement.UninstallMod(mod);
ModManagement.UninstallMods(_selectedMods.Where(x => x.IsInstalled));
}

private void ButtonUpdate_OnClick(object sender, RoutedEventArgs e)
{
ModManagement.UpdateMod(_selectedMod, _selectedVersion);
{
if (_selectedMods.Count == 1)
ModManagement.UpdateMod(_selectedMods[0], _selectedVersion);
else
ModManagement.UpdateMods(_selectedMods.Where(x => !x.UpToDate && x.IsInstalled));
}

private void ComboBoxVersion_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
Expand All @@ -180,8 +257,9 @@ private void ComboBoxVersion_OnSelectionChanged(object sender, SelectionChangedE
}

private void UpdateUpdateButton()
{
var mod = _selectedMod;
{
if (_selectedMods.Count != 1) return;
var mod = _selectedMods[0];
if (!mod.IsInstalled) return;

// Set the update button text to either update or downgrade depending on the selected version
Expand Down
3 changes: 2 additions & 1 deletion DeliCounter/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ private void NavView_OnItemInvoked(NavigationView sender, NavigationViewItemInvo
CurrentPage = tag;
var page = _pages[tag].Item1;
NavViewContent.Navigate(page);
Drawer.IsPaneOpen = _pages[tag].Item2;
Drawer.IsPaneOpen = _pages[tag].Item2;
ModManagementDrawer.ClearSelected();
}

private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
Expand Down
2 changes: 1 addition & 1 deletion DeliCounter/Pages/ModListing.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
x:Name="ModList"
DockPanel.Dock="Bottom"
BorderThickness="1"
SelectionMode="Single"
SelectionMode="Extended"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
SelectionChanged="ModList_SelectionChanged">
<ListView.ItemContainerStyle>
Expand Down
6 changes: 4 additions & 2 deletions DeliCounter/Pages/ModListing.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ private void Update()

private void ModList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var drawer = MainWindow.Instance.ModManagementDrawer;
drawer.SetMod(((ModListItem)ModList.SelectedItem)?.Mod);
var drawer = MainWindow.Instance.ModManagementDrawer;
drawer.AddSelected(e.AddedItems);
drawer.RemoveSelected(e.RemovedItems);
drawer.SelectedUpdated();
}

private void ModItem_DoubleClick(object sender, MouseButtonEventArgs e)
Expand Down
2 changes: 1 addition & 1 deletion DeliCounter/Pages/SearchPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
x:Name="ModList"
DockPanel.Dock="Bottom"
BorderThickness="1"
SelectionMode="Single"
SelectionMode="Extended"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
SelectionChanged="ModList_SelectionChanged">
<ListView.ItemContainerStyle>
Expand Down
6 changes: 4 additions & 2 deletions DeliCounter/Pages/SearchPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ private void Instance_InstalledModsUpdated()

private void ModList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var drawer = MainWindow.Instance.ModManagementDrawer;
drawer.SetMod(((ModListItem)ModList.SelectedItem)?.Mod);
var drawer = MainWindow.Instance.ModManagementDrawer;
drawer.AddSelected(e.AddedItems);
drawer.RemoveSelected(e.RemovedItems);
drawer.SelectedUpdated();
}

private void TextBoxSearch_OnTextChanged(object sender, TextChangedEventArgs e)
Expand Down

0 comments on commit 6dceccf

Please sign in to comment.