diff --git a/Changelog.md b/Changelog.md
index d39b145d..8b095c6b 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,12 @@
# CHANGELOG
-
## COMPASS v1.8.7 (27 May 2025)
+
## COMPASS v1.8.8 (28 June 2025)
+
+### Fixes
+- Fix crashes on commands in context menu when no items are selected.
+- Fix potential crash when looking at the change logs in the settings
+- Fix a crash when deleting a collection when a file is locked
+- Fix an issue where the open collection was copied to the new data location after changing it
+## COMPASS v1.8.7 (27 May 2025)
### Fixes
diff --git a/Deployment/install.iss b/Deployment/install.iss
index 66d1882a..90a2e90d 100644
--- a/Deployment/install.iss
+++ b/Deployment/install.iss
@@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "COMPASS"
-#define MyAppVersion "1.8.7"
+#define MyAppVersion "1.8.8"
#define MyAppPublisher "Paul De Smul"
#define MyAppURL "https://www.compassapp.info"
#define MyAppExeName "COMPASS.exe"
diff --git a/src/COMPASS.csproj b/src/COMPASS.csproj
index 14d18365..893df0a9 100644
--- a/src/COMPASS.csproj
+++ b/src/COMPASS.csproj
@@ -69,8 +69,8 @@
-
-
+
+
diff --git a/src/Models/CodexCollection.cs b/src/Models/CodexCollection.cs
index c83e81c9..9d3c10da 100644
--- a/src/Models/CodexCollection.cs
+++ b/src/Models/CodexCollection.cs
@@ -254,7 +254,7 @@ public void Save()
try
{
- Directory.CreateDirectory(UserFilesPath);
+ Directory.CreateDirectory(FullDataPath);
}
catch (Exception ex)
{
@@ -585,6 +585,8 @@ public void DeleteCodex(Codex toDelete)
public void DeleteCodices(IList toDelete)
{
+ if (!toDelete.Any()) return;
+
Notification deleteWarnNotification = Notification.AreYouSureNotification;
deleteWarnNotification.Body = $"You are about to remove {toDelete.Count} item{(toDelete.Count > 1 ? @"s" : @"")}. " +
$"This cannot be undone. " +
@@ -604,7 +606,8 @@ public void DeleteCodices(IList toDelete)
public void BanishCodices(IList toBanish)
{
- if (toBanish is null) return;
+ if (!toBanish.SafeAny()) return;
+
IEnumerable toBanishPaths = toBanish.Select(codex => codex.Sources.Path);
IEnumerable toBanishURLs = toBanish.Select(codex => codex.Sources.SourceURL);
IEnumerable toBanishStrings = toBanishPaths
diff --git a/src/Models/CodexProperties/EnumerableProperty.cs b/src/Models/CodexProperties/EnumerableProperty.cs
index 423224a2..c2ff0018 100644
--- a/src/Models/CodexProperties/EnumerableProperty.cs
+++ b/src/Models/CodexProperties/EnumerableProperty.cs
@@ -33,7 +33,7 @@ public override bool HasNewValue(IHasCodexMetadata toEvaluate, IHasCodexMetadata
return true;
}
- return !newVal!.SequenceEqual(refVal);
+ return !newVal.SequenceEqual(refVal);
}
}
}
diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs
index d1d084b2..7d1b1b9d 100644
--- a/src/Properties/AssemblyInfo.cs
+++ b/src/Properties/AssemblyInfo.cs
@@ -40,7 +40,7 @@
// app, or any theme specific resource dictionaries)
)]
-[assembly: AssemblyVersion("1.8.7")]
+[assembly: AssemblyVersion("1.8.8")]
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows")]
diff --git a/src/Services/CoverService.cs b/src/Services/CoverService.cs
index 0dbc4ca2..510ee452 100644
--- a/src/Services/CoverService.cs
+++ b/src/Services/CoverService.cs
@@ -87,6 +87,8 @@ public static async Task GetCover(Codex codex, ChooseMetaDataViewModel? chooseMe
public static async Task GetCover(List codices)
{
+ if (!codices.Any()) return;
+
var progressVM = ProgressViewModel.GetInstance();
progressVM.ResetCounter();
progressVM.TotalAmount = codices.Count;
diff --git a/src/Tools/ExtensionMethods.cs b/src/Tools/ExtensionMethods.cs
index 47c81896..68c89770 100644
--- a/src/Tools/ExtensionMethods.cs
+++ b/src/Tools/ExtensionMethods.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -172,7 +173,7 @@ public static IEnumerable Flatten(this IEnumerable l, string method = "
}
}
- public static bool SafeAny(this IEnumerable? l) => l is not null && l.Any();
+ public static bool SafeAny([NotNullWhen(true)] this IEnumerable? l) => l is not null && l.Any();
#endregion
}
}
diff --git a/src/Tools/Utils.cs b/src/Tools/Utils.cs
index 467e3189..1fb42a43 100644
--- a/src/Tools/Utils.cs
+++ b/src/Tools/Utils.cs
@@ -1,6 +1,8 @@
using COMPASS.Models;
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
namespace COMPASS.Tools
{
@@ -16,5 +18,28 @@ public static int GetAvailableID(IEnumerable collection) where T : IHasID
}
return tempID;
}
+
+ public static void Retry(int maxAttempts, Action action, int retryDelayMs = 1000, Action? onFailedAttempt = null) =>
+ Retry(maxAttempts, action, retryDelayMs, onFailedAttempt);
+ public static void Retry(int maxAttempts, Action action, int retryDelayMs = 1000, Action? onFailedAttempt = null) where T : Exception
+ {
+ for (int i = 0; i < maxAttempts; i++)
+ {
+ try
+ {
+ action();
+ return;
+ }
+ catch (T e) when (i < maxAttempts - 1) //failure in last attempt will not be caught by design
+ {
+ onFailedAttempt?.Invoke(e);
+ if (retryDelayMs > 0)
+ {
+ Thread.Sleep(retryDelayMs);
+ }
+ }
+ }
+ }
+
}
}
diff --git a/src/ViewModels/CodexViewModel.cs b/src/ViewModels/CodexViewModel.cs
index cdcc6e3c..b16a18cd 100644
--- a/src/ViewModels/CodexViewModel.cs
+++ b/src/ViewModels/CodexViewModel.cs
@@ -108,7 +108,7 @@ public static bool CanOpenCodexOnline(Codex? toOpen)
public RelayCommand OpenSelectedCodicesCommand => _openSelectedCodicesCommand ??= new(l => OpenSelectedCodices(l?.Cast().ToList()));
public static bool OpenSelectedCodices(IList? toOpen)
{
- if (toOpen is null) return false;
+ if (!toOpen.SafeAny()) return false;
if (toOpen.Count == 1)
{
@@ -152,7 +152,7 @@ public static void EditCodex(Codex? toEdit)
public static void EditCodices(IList? toEdit)
{
List? toEditList = toEdit?.Cast().ToList();
- if (toEditList is null) return;
+ if (!toEditList.SafeAny()) return;
if (toEditList.Count == 1)
{
@@ -186,7 +186,8 @@ public static void FavoriteCodex(Codex? toFavorite)
private static void FavoriteCodices(IList? toFavorite)
{
List? toFavoriteList = toFavorite?.Cast().ToList();
- if (toFavoriteList is null) return;
+ if (!toFavoriteList.SafeAny()) return;
+
if (toFavoriteList.Count == 1)
{
FavoriteCodex(toFavoriteList.First());
@@ -247,6 +248,8 @@ public void MoveToCollection(object[]? par)
///
public static void MoveToCollection(CodexCollection targetCollection, List toMoveList)
{
+ if (!toMoveList.Any()) return;
+
//Check if target Collection is valid
if (targetCollection.DirectoryName == MainViewModel.CollectionVM.CurrentCollection.DirectoryName)
{
@@ -324,6 +327,8 @@ public static void DeleteCodex(Codex? toDelete)
public RelayCommand DeleteCodicesCommand => _deleteCodicesCommand ??= new(DeleteCodices);
public static void DeleteCodices(IList? toDelete)
{
+ if (toDelete == null || toDelete.Count == 0) return;
+
MainViewModel.CollectionVM.CurrentCollection.DeleteCodices(toDelete?.Cast().ToList() ?? new());
MainViewModel.CollectionVM.FilterVM.ReFilter();
}
@@ -341,6 +346,8 @@ public static void DeleteCodices(IList? toDelete)
public RelayCommand BanishCodicesCommand => _banishCodicesCommand ??= new(BanishCodices);
public static void BanishCodices(IList? toBanish)
{
+ if (toBanish == null || toBanish.Count == 0) return;
+
MainViewModel.CollectionVM.CurrentCollection.BanishCodices(toBanish?.Cast().ToList() ?? new());
DeleteCodices(toBanish);
}
@@ -362,6 +369,8 @@ public static async Task StartGetMetaDataProcess(Codex? codex)
}
public static async Task StartGetMetaDataProcess(IList codices)
{
+ if (!codices.Any()) return;
+
var progressVM = ProgressViewModel.GetInstance();
progressVM.ResetCounter();
progressVM.Text = "Getting MetaData";
diff --git a/src/ViewModels/CollectionViewModel.cs b/src/ViewModels/CollectionViewModel.cs
index 0594c591..33487f9e 100644
--- a/src/ViewModels/CollectionViewModel.cs
+++ b/src/ViewModels/CollectionViewModel.cs
@@ -379,9 +379,20 @@ public void DeleteCollection(CodexCollection toDelete)
//if Dir name of toDelete is empty, it will delete the entire collections folder
if (String.IsNullOrEmpty(toDelete.DirectoryName)) return;
- if (Directory.Exists(toDelete.FullDataPath)) //does not exist if collection was never saved
+
+ //possible that folder does not exist if collection was never saved
+ if (!Directory.Exists(toDelete.FullDataPath)) return;
+
+ try
+ {
+ //sometimes delete fails because a file is locked, retry could help with that
+ Utils.Retry(3, () => Directory.Delete(toDelete.FullDataPath, true),
+ onFailedAttempt: (ex) => Logger.Warn($"Failed to delete collection {toDelete.DirectoryName}, retrying...", ex)
+ );
+ }
+ catch (Exception ex)
{
- Directory.Delete(toDelete.FullDataPath, true);
+ Logger.Error($"Failed to delete collection {toDelete.DirectoryName}", ex);
}
}
diff --git a/src/ViewModels/MainViewModel.cs b/src/ViewModels/MainViewModel.cs
index 8596eb46..1bf07891 100644
--- a/src/ViewModels/MainViewModel.cs
+++ b/src/ViewModels/MainViewModel.cs
@@ -108,6 +108,8 @@ private void InitConnectionTimer()
#region Properties
+ public static bool SaveOnClose { get; set; } = true;
+
private bool _isOnline;
public bool IsOnline
{
diff --git a/src/ViewModels/SettingsViewModel.cs b/src/ViewModels/SettingsViewModel.cs
index 3299d672..891b9de0 100644
--- a/src/ViewModels/SettingsViewModel.cs
+++ b/src/ViewModels/SettingsViewModel.cs
@@ -549,13 +549,19 @@ private async Task CopyToNewDataPath()
///
public void ChangeToNewDataPath()
{
+ //save stuff in old location
MainViewModel.CollectionVM?.CurrentCollection.Save();
+ PreferencesService.GetInstance().SavePreferences();
+ //change location
CompassDataPath = NewDataPath;
Notification changeSuccessful = new("Data path changed succesfully", $"Data path was successfully changed to {CompassDataPath}. COMPASS will now restart.");
App.Container.ResolveKeyed(NotificationDisplayType.Windowed).Show(changeSuccessful);
+ //Now that datapath has been changed, don't save on close because it would save to new location
+ MainViewModel.SaveOnClose = false;
+
//Restart COMPASS
var currentExecutablePath = Environment.ProcessPath;
var args = Environment.GetCommandLineArgs();
diff --git a/src/Windows/MainWindow.xaml.cs b/src/Windows/MainWindow.xaml.cs
index 985cd47c..b853df3c 100644
--- a/src/Windows/MainWindow.xaml.cs
+++ b/src/Windows/MainWindow.xaml.cs
@@ -34,8 +34,11 @@ public MainWindow()
private void Window_Closing(object sender, CancelEventArgs e)
{
ProgressViewModel.GetInstance().CancelBackgroundTask();
- MainViewModel.CollectionVM?.CurrentCollection.Save();
- PreferencesService.GetInstance().SavePreferences();
+ if (MainViewModel.SaveOnClose)
+ {
+ MainViewModel.CollectionVM?.CurrentCollection.Save();
+ PreferencesService.GetInstance().SavePreferences();
+ }
}
#region Window management
diff --git a/src/Windows/SettingsWindow.xaml.cs b/src/Windows/SettingsWindow.xaml.cs
index 7e39acd3..a44ad1af 100644
--- a/src/Windows/SettingsWindow.xaml.cs
+++ b/src/Windows/SettingsWindow.xaml.cs
@@ -1,7 +1,9 @@
using COMPASS.Models;
using COMPASS.Services;
+using COMPASS.Tools;
using COMPASS.ViewModels;
using Microsoft.Web.WebView2.Core;
+using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
@@ -47,19 +49,27 @@ private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.
public async void LoadChangeLog()
{
- string sHTML = "" +
- "" +
- "" +
- "" +
- "Changelog" +
- "" +
- "" +
- "" +
- "" +
- "";
+ try
+ {
+ string sHTML = "" +
+ "" +
+ "" +
+ "" +
+ "Changelog" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "";
- await ChangelogWebView.EnsureCoreWebView2Async(await CoreWebView2Environment.CreateAsync(userDataFolder: VM.WebViewDataDir));
- ChangelogWebView.NavigateToString(sHTML);
+ var environment = await CoreWebView2Environment.CreateAsync(userDataFolder: VM.WebViewDataDir);
+ await ChangelogWebView.EnsureCoreWebView2Async(environment);
+ ChangelogWebView.NavigateToString(sHTML);
+ }
+ catch (Exception ex)
+ {
+ Logger.Error("failed to load changelog", ex);
+ }
}
private void SelectFolderForFolderTagPairButton_Click(object sender, RoutedEventArgs e) => NewFolderTagPairTextBox.Text = IOService.PickFolder();
diff --git a/versionInfo.xml b/versionInfo.xml
index 68d0722d..f4d68cef 100644
--- a/versionInfo.xml
+++ b/versionInfo.xml
@@ -1,6 +1,6 @@
-
- 1.8.7
- https://github.com/DSPAUL/COMPASS/releases/download/v1.8.7/COMPASS_Setup_1.8.7.exe
+ 1.8.8
+ https://github.com/DSPAUL/COMPASS/releases/download/v1.8.8/COMPASS_Setup_1.8.8.exe
false