diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3ade510491..28daef943f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -5,7 +5,7 @@ 10.0.19041.0 - 10.0.26100.57 + 10.0.26100.56 8.0.407 Martí Climent and the contributors diff --git a/src/UniGetUI.Core.LanguageEngine/Assets/Data/LanguagesReference.json b/src/UniGetUI.Core.LanguageEngine/Assets/Data/LanguagesReference.json index 7702fb6085..18da60c70c 100644 --- a/src/UniGetUI.Core.LanguageEngine/Assets/Data/LanguagesReference.json +++ b/src/UniGetUI.Core.LanguageEngine/Assets/Data/LanguagesReference.json @@ -48,6 +48,7 @@ "si": "Sinhala - සිංහල", "sl": "Slovene - Slovenščina", "sv": "Swedish - Svenska", + "ta": "Tamil - தமிழ்", "tg": "Tagalog - Tagalog", "th": "Thai - ภาษาไทย", "tr": "Turkish - Türkçe", diff --git a/src/UniGetUI.PAckageEngine.Interfaces/IPackage.cs b/src/UniGetUI.PAckageEngine.Interfaces/IPackage.cs index 6e1efa4712..d6ecd5e58e 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/IPackage.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/IPackage.cs @@ -2,6 +2,7 @@ using UniGetUI.Core.Tools; using UniGetUI.Interface.Enums; using UniGetUI.PackageEngine.Classes.Serializable; +using UniGetUI.PackageEngine.Serializable; using UniGetUI.PackageEngine.Structs; namespace UniGetUI.PackageEngine.Interfaces @@ -118,7 +119,7 @@ public interface IPackage : INotifyPropertyChanged, IEquatable /// Returns the corresponding installed Package object. Will return null if not applicable /// /// a Package object if found, null if not - public IPackage? GetInstalledPackage(); + public IReadOnlyList GetInstalledPackages(); /// /// Returns the corresponding available Package object. Will return null if not applicable @@ -155,6 +156,12 @@ public interface IPackage : INotifyPropertyChanged, IEquatable /// False if the update is a major update or the update doesn't exist, true if it's a minor update public bool IsUpdateMinor(); + /// + /// Gets the applicable install options for this package + /// + /// The package install options, or, if not overriden, the manager install options + public Task GetInstallOptions(); + public Task AsSerializableAsync(); public SerializableIncompatiblePackage AsSerializable_Incompatible(); diff --git a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs index 5574f550b1..2f0ec6af39 100644 --- a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs @@ -263,9 +263,11 @@ protected override Task HandleFailure() protected override async Task HandleSuccess() { Package.SetTag(PackageTag.Default); - Package.GetInstalledPackage()?.SetTag(PackageTag.Default); Package.GetAvailablePackage()?.SetTag(PackageTag.AlreadyInstalled); + foreach (var p in Package.GetInstalledPackages()) + p.SetTag(PackageTag.Default); + UpgradablePackagesLoader.Instance.Remove(Package); if (Settings.Get(Settings.K.AskToDeleteNewDesktopShortcuts)) diff --git a/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs b/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs index 408f94e7ba..0c8417176d 100644 --- a/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs +++ b/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs @@ -10,6 +10,7 @@ using UniGetUI.PackageEngine.Managers.ScoopManager; using UniGetUI.PackageEngine.Managers.WingetManager; using UniGetUI.PackageEngine.Managers.VcpkgManager; +using UniGetUI.PackageEngine.PackageClasses; using UniGetUI.PackageEngine.PackageLoader; namespace UniGetUI.PackageEngine @@ -74,4 +75,58 @@ public static void Initialize() } } } + + + + + public class PackageBundlesLoader : PackageBundlesLoader_A + { + public PackageBundlesLoader(IReadOnlyList managers): base(managers) + { + } + + public override async Task AddPackagesAsync(IReadOnlyList foreign_packages) + { + List added = new(); + foreach (IPackage foreign in foreign_packages) + { + IPackage? package = null; + + if (foreign is not ImportedPackage && foreign is Package native) + { + if (native.Source.IsVirtualManager) + { + Logger.Debug($"Adding native package with id={native.Id} to bundle as an INVALID package..."); + package = new InvalidImportedPackage(native.AsSerializable_Incompatible(), NullSource.Instance); + } + else + { + Logger.Debug($"Adding native package with id={native.Id} to bundle as a VALID package..."); + package = new ImportedPackage(await native.AsSerializableAsync(), native.Manager, native.Source); + } + } + else if (foreign is ImportedPackage imported) + { + Logger.Debug($"Adding loaded imported package with id={imported.Id} to bundle..."); + package = imported; + } + else if (foreign is InvalidImportedPackage invalid) + { + Logger.Debug($"Adding loaded incompatible package with id={invalid.Id} to bundle..."); + package = invalid; + } + else + { + Logger.Error($"An IPackage instance id={foreign.Id} did not match the types Package, ImportedPackage or InvalidImportedPackage. This should never be the case"); + } + + if (package is not null) + { // Here, AddForeign is not used so a single PackagesChangedEvent can be invoked. + await AddPackage(package); + added.Add(package); + } + } + InvokePackagesChangedEvent(true, added, []); + } + } } diff --git a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs index 8bdf02f41c..1622ad34e9 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs @@ -60,7 +60,7 @@ protected override Task WhenAddingPackage(IPackage package) { package.SetTag(PackageTag.IsUpgradable); } - else if (package.GetInstalledPackage() is not null) + else if (package.GetInstalledPackages().Any()) { package.SetTag(PackageTag.AlreadyInstalled); } diff --git a/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs index 0cfe4b0668..1fc4ff0e3b 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs @@ -1,15 +1,13 @@ -using UniGetUI.Core.Logging; using UniGetUI.Interface.Enums; using UniGetUI.PackageEngine.Interfaces; -using UniGetUI.PackageEngine.PackageClasses; namespace UniGetUI.PackageEngine.PackageLoader { - public class PackageBundlesLoader : AbstractPackageLoader + public abstract class PackageBundlesLoader_A : AbstractPackageLoader { - public static PackageBundlesLoader Instance = null!; + public static PackageBundlesLoader_A Instance = null!; - public PackageBundlesLoader(IReadOnlyList managers) + public PackageBundlesLoader_A(IReadOnlyList managers) : base(managers, identifier: "PACKAGE_BUNDLES", AllowMultiplePackageVersions: true, @@ -44,49 +42,11 @@ protected override Task WhenAddingPackage(IPackage package) return Task.CompletedTask; } - public async Task AddPackagesAsync(IReadOnlyList foreign_packages) - { - List added = new(); - foreach (IPackage foreign in foreign_packages) - { - IPackage? package = null; - - if (foreign is not ImportedPackage && foreign is Package native) - { - if (native.Source.IsVirtualManager) - { - Logger.Debug($"Adding native package with id={native.Id} to bundle as an INVALID package..."); - package = new InvalidImportedPackage(native.AsSerializable_Incompatible(), NullSource.Instance); - } - else - { - Logger.Debug($"Adding native package with id={native.Id} to bundle as a VALID package..."); - package = new ImportedPackage(await native.AsSerializableAsync(), native.Manager, native.Source); - } - } - else if (foreign is ImportedPackage imported) - { - Logger.Debug($"Adding loaded imported package with id={imported.Id} to bundle..."); - package = imported; - } - else if (foreign is InvalidImportedPackage invalid) - { - Logger.Debug($"Adding loaded incompatible package with id={invalid.Id} to bundle..."); - package = invalid; - } - else - { - Logger.Error($"An IPackage instance id={foreign.Id} did not match the types Package, ImportedPackage or InvalidImportedPackage. This should never be the case"); - } - - if (package is not null) - { // Here, AddForeign is not used so a single PackagesChangedEvent can be invoked. - await AddPackage(package); - added.Add(package); - } - } - InvokePackagesChangedEvent(true, added, []); - } + /* + * This method required access to the Package, ImportedPackage and InvalidPackage classes, + * but they are not defined here yet. This class will be inherited on PEInterface, with the missing member + */ + public abstract Task AddPackagesAsync(IReadOnlyList foreign_packages); public void RemoveRange(IReadOnlyList packages) { diff --git a/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj b/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj index c61da5fe6f..66dc2028a1 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj +++ b/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj @@ -1,6 +1,5 @@ - - + @@ -8,23 +7,10 @@ - - - - - - - - - - + - - - - diff --git a/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs index b060e1f2bf..375504c029 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs @@ -3,7 +3,6 @@ using UniGetUI.Core.SettingsEngine; using UniGetUI.Interface.Enums; using UniGetUI.PackageEngine.Interfaces; -using UniGetUI.PackageEngine.PackageClasses; namespace UniGetUI.PackageEngine.PackageLoader { @@ -31,18 +30,24 @@ public UpgradablePackagesLoader(IReadOnlyList managers) protected override async Task IsPackageValid(IPackage package) { - if (package.VersionString == package.NewVersionString) return false; - if (await package.HasUpdatesIgnoredAsync(package.NewVersionString)) + if (package.VersionString == package.NewVersionString) + return false; + + if (package.NewerVersionIsInstalled()) + return false; + + if (package.IsUpdateMinor() && (await package.GetInstallOptions()).SkipMinorUpdates) { - IgnoredPackages[package.Id] = package; + Logger.Info($"Ignoring package {package.Id} because it is a minor update ({package.VersionString} -> {package.NewVersionString}) and SkipMinorUpdates is set to true."); return false; } - if ((await InstallOptionsFactory.LoadApplicableAsync(package)).SkipMinorUpdates && package.IsUpdateMinor()) + + if (await package.HasUpdatesIgnoredAsync(package.NewVersionString)) { - Logger.Info($"Ignoring package {package.Id} because it is a minor update ({package.VersionString} -> {package.NewVersionString}) and SkipMinorUpdates is set to true."); + IgnoredPackages[package.Id] = package; return false; } - if (package.NewerVersionIsInstalled()) return false; + return true; } @@ -53,7 +58,9 @@ protected override IReadOnlyList LoadPackagesFromManager(IPackageManag protected override Task WhenAddingPackage(IPackage package) { package.GetAvailablePackage()?.SetTag(PackageTag.IsUpgradable); - package.GetInstalledPackage()?.SetTag(PackageTag.IsUpgradable); + + foreach(var p in package.GetInstalledPackages()) + p.SetTag(PackageTag.IsUpgradable); return Task.CompletedTask; } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs index 2a6fd860df..eaebd60a26 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs @@ -213,13 +213,8 @@ private IReadOnlyList _findPackages(string query, bool SecondAttempt) task.Wait(); } - Package[] packages = task.GetAwaiter().GetResult().ToArray(); - - for (int i = 0; i < packages.Length; i++) - { - packages[i] = PackageCacher.GetAvailablePackage(packages[i]); - } - Logger.Info($"Found {packages.Length} available packages from {Name} with the query {query}"); + var packages = task.GetAwaiter().GetResult(); + Logger.Info($"Found {packages.Count} available packages from {Name} with the query {query}"); return packages; } catch (Exception e) @@ -263,14 +258,8 @@ private IReadOnlyList _getAvailableUpdates(bool SecondAttempt) task.Wait(); } - Package[] packages = task.GetAwaiter().GetResult().ToArray(); - - for (int i = 0; i < packages.Length; i++) - { - packages[i] = PackageCacher.GetUpgradablePackage(packages[i]); - } - - Logger.Info($"Found {packages.Length} available updates from {Name}"); + var packages = task.GetAwaiter().GetResult(); + Logger.Info($"Found {packages.Count} available updates from {Name}"); return packages; } catch (Exception e) @@ -312,14 +301,8 @@ private IReadOnlyList _getInstalledPackages(bool SecondAttempt) task.Wait(); } - Package[] packages = task.GetAwaiter().GetResult().ToArray(); - - for (int i = 0; i < packages.Length; i++) - { - packages[i] = PackageCacher.GetInstalledPackage(packages[i]); - } - - Logger.Info($"Found {packages.Length} installed packages from {Name}"); + var packages = task.GetAwaiter().GetResult(); + Logger.Info($"Found {packages.Count} installed packages from {Name}"); return packages; } catch (Exception e) @@ -370,9 +353,12 @@ public virtual void RefreshPackageIndexes() Logger.Debug($"Manager {Name} has not implemented RefreshPackageIndexes"); } + /// + /// Attempt a live, fast, repair method when an exception occurs (for example, reconnect to COM Server) + /// public virtual void AttemptFastRepair() { - // Implementing this method is optional + Logger.Debug($"Manager {Name} has not implemented AttemptFastRepair"); } } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageCacher.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageCacher.cs deleted file mode 100644 index 956b67e754..0000000000 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageCacher.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Collections.Concurrent; -using UniGetUI.PackageEngine.PackageClasses; - -namespace UniGetUI.PackageEngine.Classes.Packages -{ - internal static class PackageCacher - { - private static readonly ConcurrentDictionary __available_pkgs = []; - private static readonly ConcurrentDictionary __upgradable_pkgs = []; - private static readonly ConcurrentDictionary __installed_pkgs = []; - - /// - /// Will check if a given Package is already in the cache. If not, it will be added to it - /// This checks only the "Discover Packages" cache - /// - /// The package to check - /// The already existing package if any, otherwise p - public static Package GetAvailablePackage(Package p) - { - Package? new_package = GetAvailablePackageOrNull(p); - if (new_package is null) - { - AddPackageToCache(p, __available_pkgs); - } - - return new_package ?? p; - } - - /// - /// Will check if a given Package is already in the cache. If not, it will be added to it - /// This checks only the "Software Updates" cache - /// - /// The package to check - /// The already existing package if any, otherwise p - public static Package GetUpgradablePackage(Package p) - { - Package? new_package = GetUpgradablePackageOrNull(p); - if (new_package is null) - { - AddPackageToCache(p, __upgradable_pkgs); - } - - return new_package ?? p; - } - - /// - /// Will check if a given Package is already in the cache. If not, it will be added to it - /// This checks only the "Installed Packages" cache - /// - /// The package to check - /// The already existing package if any, otherwise p - public static Package GetInstalledPackage(Package p) - { - Package? new_package = GetInstalledPackageOrNull(p); - if (new_package is null) - { - AddPackageToCache(p, __installed_pkgs); - } - - return new_package ?? p; - } - - /// - /// Will check if a given Package is already in the cache. - /// This checks only the "Discover Packages" cache - /// - /// The package to check - /// The already existing package if any, otherwise null - public static Package? GetAvailablePackageOrNull(Package other) - { - return __available_pkgs.GetValueOrDefault(other.GetHash()); - } - - /// - /// Will check if a given Package is already in the cache. - /// This checks only the "Software Updates" cache - /// - /// The package to check - /// The already existing package if any, otherwise null - public static Package? GetUpgradablePackageOrNull(Package other) - { - return __upgradable_pkgs.GetValueOrDefault(other.GetHash()); - } - - /// - /// Will check if a given Package is already in the cache. - /// This checks only the "Installed Packages" cache - /// - /// The package to check - /// The already existing package if any, otherwise null - public static Package? GetInstalledPackageOrNull(Package other) - { - return __installed_pkgs.GetValueOrDefault(other.GetVersionedHash()); - } - - /// - /// Checks whether a Package with a newer version has been found in the Installed Packages cache - /// - /// The package to check again - /// True if a newer version was found, false otherwise - public static bool NewerVersionIsInstalled(Package other) - { - foreach (Package found in __installed_pkgs.Values) - { - if (found.IsEquivalentTo(other) && found.NormalizedVersion >= other.NormalizedNewVersion) - { - return true; - } - } - - return false; - } - - private static void AddPackageToCache(Package package, ConcurrentDictionary map) - { - long hash = map == __installed_pkgs ? package.GetVersionedHash() : package.GetHash(); - map.TryAdd(hash, package); - } - } -} diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs index df24b8f36d..7b0e25390b 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs @@ -45,6 +45,9 @@ public async Task RegisterAndGetPackageAsync() return package; } + public override Task GetInstallOptions() + => Task.FromResult(installation_options.Copy()); + public override Task AsSerializableAsync() { return Task.FromResult(new SerializablePackage diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs index 8f5ebd9e90..85072a6f94 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs @@ -6,6 +6,7 @@ using UniGetUI.PackageEngine.Classes.Serializable; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageEngine.Serializable; using UniGetUI.PackageEngine.Structs; namespace UniGetUI.PackageEngine.PackageClasses @@ -75,6 +76,9 @@ public Task AddToIgnoredUpdatesAsync(string version = "*") return Task.CompletedTask; } + public Task GetInstallOptions() + => Task.FromResult(new InstallOptions()); + public Task AsSerializableAsync() { throw new NotImplementedException(); @@ -126,7 +130,7 @@ public Task GetIgnoredUpdatesVersionAsync() return Task.FromResult(String.Empty); } - public IPackage? GetInstalledPackage() + public IReadOnlyList GetInstalledPackages() { return null; } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs index e2474f8fd4..9f151da4d3 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs @@ -10,6 +10,8 @@ using UniGetUI.PackageEngine.Classes.Packages.Classes; using UniGetUI.PackageEngine.Classes.Serializable; using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.PackageEngine.Serializable; using UniGetUI.PackageEngine.Structs; namespace UniGetUI.PackageEngine.PackageClasses @@ -190,7 +192,8 @@ public virtual async Task AddToIgnoredUpdatesAsync(string version = "*") try { await Task.Run(() => IgnoredUpdatesDatabase.Add(_ignoredId, version)); - GetInstalledPackage()?.SetTag(PackageTag.Pinned); + foreach(var p in GetInstalledPackages()) + p.SetTag(PackageTag.Pinned); } catch (Exception ex) { @@ -204,7 +207,8 @@ public virtual async Task RemoveFromIgnoredUpdatesAsync() try { await Task.Run(() => IgnoredUpdatesDatabase.Remove(_ignoredId)); - GetInstalledPackage()?.SetTag(PackageTag.Default); + foreach(var p in GetInstalledPackages()) + p.SetTag(PackageTag.Default); } catch (Exception ex) { @@ -258,14 +262,15 @@ protected void OnPropertyChanged([CallerMemberName] string? name = null) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } - public IPackage? GetInstalledPackage() - => PackageCacher.GetInstalledPackageOrNull(this); public IPackage? GetAvailablePackage() - => PackageCacher.GetAvailablePackageOrNull(this); + => DiscoverablePackagesLoader.Instance.GetEquivalentPackage(this); public IPackage? GetUpgradablePackage() - => PackageCacher.GetUpgradablePackageOrNull(this); + => UpgradablePackagesLoader.Instance.GetEquivalentPackage(this); + + public IReadOnlyList GetInstalledPackages() + => InstalledPackagesLoader.Instance.GetEquivalentPackages(this); public virtual void SetTag(PackageTag tag) { @@ -274,7 +279,15 @@ public virtual void SetTag(PackageTag tag) public virtual bool NewerVersionIsInstalled() { - return PackageCacher.NewerVersionIsInstalled(this); + foreach (var p in GetInstalledPackages()) + { + if (p.NormalizedVersion >= this.NormalizedNewVersion) + { + return true; + } + } + + return false; } public async Task GetInstallerFileName() @@ -299,6 +312,9 @@ public virtual bool IsUpdateMinor() (NormalizedVersion.Patch != NormalizedNewVersion.Patch || NormalizedVersion.Remainder != NormalizedNewVersion.Remainder); } + public virtual Task GetInstallOptions() + => InstallOptionsFactory.LoadApplicableAsync(this); + public virtual async Task AsSerializableAsync() { return new SerializablePackage diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj index 7a21a8a0f8..ceb88260c2 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj @@ -13,6 +13,7 @@ + diff --git a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs index 2317e6d96b..73267e0277 100644 --- a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs @@ -105,7 +105,7 @@ public PackageDetailsPage(IPackage package, OperationType role, TEL_InstallRefer AvailablePackage = Package.GetAvailablePackage(); UpgradablePackage = Package.GetUpgradablePackage(); - InstalledPackage = UpgradablePackage?.GetInstalledPackage() ?? Package.GetInstalledPackage(); + InstalledPackage = UpgradablePackage?.GetInstalledPackages().FirstOrDefault(); var options = InstallOptionsFactory.LoadForPackage(package); InstallOptionsPage = new InstallOptionsPage(package, OperationRole, options);